struct mbuf *m;
struct bootp_t *rbp;
struct sockaddr_in saddr, daddr;
- struct in_addr dns_addr;
int dhcp_msg_type, val;
uint8_t *q;
memcpy(q, &saddr.sin_addr, 4);
q += 4;
- *q++ = RFC1533_DNS;
- *q++ = 4;
- dns_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_DNS);
- memcpy(q, &dns_addr, 4);
- q += 4;
+ if (dns_addr_valid) {
+ struct in_addr guest_dns_addr;
+ *q++ = RFC1533_DNS;
+ *q++ = 4;
+ guest_dns_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_DNS);
+ memcpy(q, &guest_dns_addr, 4);
+ q += 4;
+ }
*q++ = RFC2132_LEASE_TIME;
*q++ = 4;
struct in_addr our_addr;
/* host dns address */
struct in_addr dns_addr;
+int dns_addr_valid;
/* host loopback address */
struct in_addr loopback_addr;
#ifdef _WIN32
-static int get_dns_addr(struct in_addr *pdns_addr)
+static bool get_dns_addr(struct in_addr *pdns_addr)
{
FIXED_INFO *FixedInfo=NULL;
ULONG BufLen;
GlobalFree(FixedInfo);
FixedInfo = NULL;
}
- return -1;
+ return false;
}
pIPAddr = &(FixedInfo->DnsServerList);
- inet_aton(pIPAddr->IpAddress.String, &tmp_addr);
+ if (!inet_aton(pIPAddr->IpAddress.String, &tmp_addr)) {
+ if (FixedInfo) {
+ GlobalFree(FixedInfo);
+ FixedInfo = NULL;
+ }
+ return false;
+ }
*pdns_addr = tmp_addr;
#if 0
printf( "DNS Servers:\n" );
GlobalFree(FixedInfo);
FixedInfo = NULL;
}
- return 0;
+ return true;
}
#else
-static int get_dns_addr(struct in_addr *pdns_addr)
+static bool record_dns_server(const char *server, struct in_addr *pdns_addr,
+ int *found4, int *found6)
+{
+ struct in_addr tmp_addr;
+
+ if (!inet_aton(server, &tmp_addr)) {
+#ifdef AF_INET6
+ struct in6_addr tmp_addr6;
+ if (inet_pton(AF_INET6, server, &tmp_addr6) == 1)
+ (*found6)++;
+#endif
+ return false;
+ }
+
+ if (!*found4)
+ *pdns_addr = tmp_addr;
+ else
+ lprint(", ");
+ if (++*found4 > 3) {
+ lprint("(more)");
+ return true;
+ }
+ lprint("%s", inet_ntoa(tmp_addr));
+ return false;
+}
+
+static bool get_dns_addr(struct in_addr *pdns_addr)
{
char buff[512];
char buff2[256+1];
FILE *f;
- int found = 0;
- struct in_addr tmp_addr;
-
+ int found4 = 0;
+ int found6 = 0;
+
f = fopen("/etc/resolv.conf", "r");
- if (!f)
- return -1;
+ if (!f) {
+ write_log("SLIRP: no resolver configuration found, DNS disabled\n");
+ return false;
+ }
lprint("IP address of your DNS(s): ");
while (fgets(buff, 512, f) != NULL) {
if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
- if (!inet_aton(buff2, &tmp_addr))
- continue;
- if (tmp_addr.s_addr == loopback_addr.s_addr)
- tmp_addr = our_addr;
- /* If it's the first one, set it to dns_addr */
- if (!found)
- *pdns_addr = tmp_addr;
- else
- lprint(", ");
- if (++found > 3) {
- lprint("(more)");
+ if (record_dns_server(buff2, pdns_addr, &found4, &found6))
break;
- } else
- lprint("%s", inet_ntoa(tmp_addr));
}
}
fclose(f);
- if (!found)
- return -1;
- return 0;
+ if (!found4) {
+ if (found6) {
+ write_log("SLIRP: only IPv6 DNS servers found, DNS forwarding disabled\n");
+ } else {
+ write_log("SLIRP: no IPv4 DNS server found, DNS forwarding disabled\n");
+ }
+ return false;
+ }
+ return true;
}
#endif
/* set default addresses */
inet_aton("127.0.0.1", &loopback_addr);
- if (get_dns_addr(&dns_addr) < 0)
- return -1;
+ dns_addr_valid = get_dns_addr(&dns_addr);
inet_aton(CTL_SPECIAL, &special_addr);
alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS);
switch(ar_op) {
case ARPOP_REQUEST:
if (!memcmp(ah->ar_tip, &special_addr, 3)) {
- if (ah->ar_tip[3] == CTL_DNS || ah->ar_tip[3] == CTL_ALIAS)
+ if ((ah->ar_tip[3] == CTL_DNS && dns_addr_valid) || ah->ar_tip[3] == CTL_ALIAS)
goto arp_ok;
for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
if (ex_ptr->ex_addr == ah->ar_tip[3])