diff options
author | Liu Aleaxander <Aleaxander@gmail.com> | 2009-08-21 11:41:43 +0800 |
---|---|---|
committer | Liu Aleaxander <Aleaxander@gmail.com> | 2009-08-21 11:41:43 +0800 |
commit | 4d5026e38d741a75b0fdfd2a04f40dc43f544b76 (patch) | |
tree | b988f7985893a19622decb2bee99411f807f1163 | |
parent | 20a5fcfeb198143ca55cc21cf5ceeb6af80c2548 (diff) | |
download | syslinux-4d5026e38d741a75b0fdfd2a04f40dc43f544b76.tar.gz |
Core:PXELINUX: dns_resolv problem resolved.
Now the dns_resolv program can work correctly now except sometimes you should add some
DNS servers manually by yourself if your current DNS server can not work, this mostly happen
when you use something like Qemu.
And, we added a host c32 module written by hpa, as a dns resolver test.
Signed-off-by: Liu Aleaxander <Aleaxander@gmail.com>
-rw-r--r-- | com32/modules/Makefile | 2 | ||||
-rw-r--r-- | com32/modules/host.c | 42 | ||||
-rw-r--r-- | core/fs/pxe/dhcp_option.c | 11 | ||||
-rw-r--r-- | core/fs/pxe/dnsresolv.c | 34 |
4 files changed, 74 insertions, 15 deletions
diff --git a/com32/modules/Makefile b/com32/modules/Makefile index e3155bd5..e0e103b7 100644 --- a/com32/modules/Makefile +++ b/com32/modules/Makefile @@ -21,7 +21,7 @@ include ../MCONFIG MODULES = chain.c32 config.c32 ethersel.c32 dmitest.c32 cpuidtest.c32 \ pcitest.c32 elf.c32 linux.c32 reboot.c32 pmload.c32 meminfo.c32 \ sdi.c32 sanboot.c32 ifcpu64.c32 vesainfo.c32 kbdmap.c32 cmd.c32 \ - vpdtest.c32 + vpdtest.c32 host.c32 TESTFILES = diff --git a/com32/modules/host.c b/com32/modules/host.c new file mode 100644 index 00000000..94ca876d --- /dev/null +++ b/com32/modules/host.c @@ -0,0 +1,42 @@ +#include <stdio.h> +#include <console.h> +#include <string.h> +#include <netinet/in.h> +#include <com32.h> + +static struct in_addr dnsresolve(const char *hostname) +{ + com32sys_t regs; + struct in_addr addr; + + strcpy(__com32.cs_bounce, hostname); + + regs.eax.w[0] = 0x0010; + regs.es = SEG(__com32.cs_bounce); + regs.ebx.w[0] = OFFS(__com32.cs_bounce); + __intcall(0x22, ®s, ®s); + + addr.s_addr = regs.eax.l; + return addr; +} + +int main(int argc, char *argv[]) +{ + int i; + struct in_addr addr; + + openconsole(&dev_null_r, &dev_stdcon_w); + + for (i = 1; i < argc; i++) { + addr = dnsresolve(argv[i]); + + printf("%-39s %08X %d.%d.%d.%d\n", + argv[i], ntohl(addr.s_addr), + ((uint8_t *)&addr.s_addr)[0], + ((uint8_t *)&addr.s_addr)[1], + ((uint8_t *)&addr.s_addr)[2], + ((uint8_t *)&addr.s_addr)[3]); + } + + return 0; +} diff --git a/core/fs/pxe/dhcp_option.c b/core/fs/pxe/dhcp_option.c index b44f20de..4e40060d 100644 --- a/core/fs/pxe/dhcp_option.c +++ b/core/fs/pxe/dhcp_option.c @@ -32,6 +32,17 @@ static void dns_servers(void *data, int opt_len) dns_server[i] = *(uint32_t *)data; data += 4; } + +#if 0 + /* + * if you find you got no corret DNS server, you can add + * it here manually. BUT be carefull the DNS_MAX_SERVERS + */ + if (i < DNS_MAX_SERVERS ) { + dns_server[i++] = your_master_dns_server; + dns_server[i++] = your_second_dns_server; + } +#endif } static void local_domain(void *data, int opt_len) diff --git a/core/fs/pxe/dnsresolv.c b/core/fs/pxe/dnsresolv.c index 081b049b..ec6342f3 100644 --- a/core/fs/pxe/dnsresolv.c +++ b/core/fs/pxe/dnsresolv.c @@ -41,6 +41,7 @@ struct dnsrr { uint32_t dns_server[DNS_MAX_SERVERS] = {0, }; + /* * Turn a string in _src_ into a DNS "label set" in _dst_; returns the * number of dots encountered. On return, both src and dst are updated. @@ -49,9 +50,12 @@ int dns_mangle(char **dst, char **src) { char *p = *src; char *q = *dst; - int dots = 0; - int flag = 0; + char *count_ptr; char c; + int dots = 0; + + count_ptr = q; + *q++ = 0; while (1) { c = *p++; @@ -59,17 +63,17 @@ int dns_mangle(char **dst, char **src) break; if (c == '.') { dots++; - flag = *q; + count_ptr = q; *q++ = 0; continue; } - flag++; + *count_ptr += 1; *q++ = c; } - if (flag) - *dst++ = 0; + if (*count_ptr) + *q++ = 0; /* update the strings */ *src = --p; @@ -107,17 +111,17 @@ static int dns_compare(char *s1, char *s2) /* * Skip past a DNS label set in DS:SI */ -static char *dns_skiplabel(char *dns) +static char *dns_skiplabel(char *label) { uint8_t c; while (1) { - c = *dns++; + c = *label++; if (c >= 0xc0) - return ++dns; /* pointer is two bytes */ + return ++label; /* pointer is two bytes */ if (c == 0) - return dns; - dns += c; + return label; + label += c; } } @@ -174,7 +178,8 @@ uint32_t dns_resolv(char **name) /* Now send it to name server */ timeout_ptr = TimeoutTable; timeout = *timeout_ptr++; - while ((srv = *srv_ptr++)) { + while (srv_ptr < dns_server + DNS_MAX_SERVERS) { + srv = *srv_ptr++; uw_pkt.status = 0; uw_pkt.sip = srv; uw_pkt.gip = ((srv ^ MyIP) & Netmask) ? Gateway : 0; @@ -188,7 +193,7 @@ uint32_t dns_resolv(char **name) continue; oldtime = BIOS_timer; - while (oldtime + timeout <= BIOS_timer) { + while (oldtime + timeout >= BIOS_timer) { ur_pkt.status = 0; ur_pkt.sip = srv; ur_pkt.dip = MyIP; @@ -227,7 +232,8 @@ uint32_t dns_resolv(char **name) /* Parse the replies */ while (reps--) { same = dns_compare(p, (char *)(DNSSendBuf + sizeof(struct dnshdr))); - rr = (struct dnsrr *)dns_skiplabel(p); + p = dns_skiplabel(p); + rr = (struct dnsrr *)p; rd_len = htons(rr->rdlength); if (same && rd_len == 4 && htons(rr->type) == 1 && /* TYPE == A */ |