summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiu Aleaxander <Aleaxander@gmail.com>2009-08-21 11:41:43 +0800
committerLiu Aleaxander <Aleaxander@gmail.com>2009-08-21 11:41:43 +0800
commit4d5026e38d741a75b0fdfd2a04f40dc43f544b76 (patch)
treeb988f7985893a19622decb2bee99411f807f1163
parent20a5fcfeb198143ca55cc21cf5ceeb6af80c2548 (diff)
downloadsyslinux-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/Makefile2
-rw-r--r--com32/modules/host.c42
-rw-r--r--core/fs/pxe/dhcp_option.c11
-rw-r--r--core/fs/pxe/dnsresolv.c34
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, &regs, &regs);
+
+ 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 */