[PATCH] iphlpapi: Retrieve DNS servers from /etc/resolv.conf if possible

Bruno Jesus 00cpxxx at gmail.com
Tue Jan 31 02:36:43 CST 2017


Tested on FreeBSD 10 and PC-BSD 9 where it gives me the unimplemented message (and Debian by changing some defines).

Signed-off-by: Bruno Jesus <00cpxxx at gmail.com>
---
 dlls/iphlpapi/iphlpapi_main.c | 61 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c
index 54f7a37..2cd5c80 100644
--- a/dlls/iphlpapi/iphlpapi_main.c
+++ b/dlls/iphlpapi/iphlpapi_main.c
@@ -1343,6 +1343,67 @@ static int get_dns_servers( SOCKADDR_STORAGE *servers, int num, BOOL ip4_only )
 
 static int get_dns_servers( SOCKADDR_STORAGE *servers, int num, BOOL ip4_only )
 {
+    /* if no good ways are available try parsing /etc/resolv.conf */
+    FILE *fp;
+
+    if ((fp = fopen("/etc/resolv.conf", "r")))
+    {
+        char buf[512], *ptr, *end;
+        int family, count[2] = {0, 0};
+        SOCKADDR_STORAGE *addr = servers;
+        union
+        {
+            struct in_addr ip;
+            struct in6_addr ip6;
+            char ptr;
+        } data;
+
+        while ((ptr = fgets(buf, sizeof(buf), fp)))
+        {
+            if (strncmp(ptr, "nameserver", 10)) continue;
+            ptr += 10;
+            while (*ptr == ' ') ptr++;
+
+            end = ptr;
+            while (*end != '\0' && *end != '\n' && *end != '#') end++;
+            *end = '\0';
+
+            family = strchr(ptr, ':') ? AF_INET6 : AF_INET;
+            if (family == AF_INET6 && ip4_only) continue;
+
+#ifdef HAVE_INET_PTON
+            if (inet_pton(family, ptr, &data.ptr) != 1) continue;
+            count[family == AF_INET ? 0 : 1]++;
+#else
+            if (family == AF_INET6 || inet_aton(ptr, &data.ip) != 1) continue;
+            count[0]++;
+#endif
+            if (!servers || !num) continue;
+
+            if (family == AF_INET6)
+            {
+                struct sockaddr_in6 ip6;
+
+                memset(&ip6, 0, sizeof(ip6));
+                memcpy(&ip6.sin6_addr, &data.ip6, sizeof(data.ip6));
+                sockaddr_in6_to_WS_storage(addr, &ip6);
+            }
+            else
+            {
+                struct sockaddr_in ip4;
+
+                ip4.sin_port = 0;
+                ip4.sin_addr.s_addr = data.ip.s_addr;
+                sockaddr_in_to_WS_storage(addr, &ip4);
+            }
+
+            if (++addr >= servers + num) break;
+        }
+
+        fclose(fp);
+        return ip4_only ? count[0] : count[0] + count[1];
+    }
+
     FIXME("Unimplemented on this system\n");
     return 0;
 }
-- 
2.9.3




More information about the wine-patches mailing list