Module: wine Branch: master Commit: 1a1e2d907a3d165897e55aa5f7ea900df1a19917 URL: https://gitlab.winehq.org/wine/wine/-/commit/1a1e2d907a3d165897e55aa5f7ea900...
Author: Paul Gofman pgofman@codeweavers.com Date: Fri Oct 20 14:03:20 2023 -0600
dnsapi: Handle IP address as DNS name in DnsQuery_UTF8().
---
dlls/dnsapi/query.c | 42 ++++++++++++++++++++++++++++++++++++++++++ dlls/dnsapi/tests/query.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+)
diff --git a/dlls/dnsapi/query.c b/dlls/dnsapi/query.c index 1802e93dd75..d5f46d0a32e 100644 --- a/dlls/dnsapi/query.c +++ b/dlls/dnsapi/query.c @@ -21,11 +21,15 @@ #include <stdarg.h> #include "windef.h" #include "winbase.h" +#include "winternl.h" #include "winerror.h" #include "winnls.h" #include "windns.h" #include "nb30.h" #include "ws2def.h" +#include "in6addr.h" +#include "inaddr.h" +#include "ip2string.h"
#include "wine/debug.h" #include "dnsapi.h" @@ -170,6 +174,7 @@ DNS_STATUS WINAPI DnsQuery_UTF8( const char *name, WORD type, DWORD options, voi unsigned char answer[4096]; DWORD len = sizeof(answer); struct query_params query_params = { name, type, options, answer, &len }; + const char *end;
TRACE( "(%s, %s, %#lx, %p, %p, %p)\n", debugstr_a(name), debugstr_type( type ), options, servers, result, reserved ); @@ -177,6 +182,43 @@ DNS_STATUS WINAPI DnsQuery_UTF8( const char *name, WORD type, DWORD options, voi if (!name || !result) return ERROR_INVALID_PARAMETER;
+ if (type == DNS_TYPE_A) + { + struct in_addr addr; + + if (!RtlIpv4StringToAddressA(name, TRUE, &end, &addr) && !*end) + { + DNS_RECORDA *r = calloc(1, sizeof(*r)); + r->pName = strdup(name); + r->wType = DNS_TYPE_A; + r->wDataLength = sizeof(r->Data.A); + r->dwTtl = 604800; + r->Flags.S.Reserved = 0x20; + r->Flags.S.CharSet = DnsCharSetUtf8; + r->Data.A.IpAddress = addr.s_addr; + *result = r; + return ERROR_SUCCESS; + } + } + else if (type == DNS_TYPE_AAAA) + { + struct in6_addr addr; + + if (!RtlIpv6StringToAddressA(name, &end, &addr) && !*end) + { + DNS_RECORDA *r = calloc(1, sizeof(*r)); + r->pName = strdup(name); + r->wType = DNS_TYPE_AAAA; + r->wDataLength = sizeof(r->Data.AAAA); + r->dwTtl = 604800; + r->Flags.S.Reserved = 0x20; + r->Flags.S.CharSet = DnsCharSetUtf8; + memcpy(&r->Data.AAAA.Ip6Address, &addr, sizeof(r->Data.AAAA.Ip6Address)); + *result = r; + return ERROR_SUCCESS; + } + } + if ((ret = RESOLV_CALL( set_serverlist, servers ))) return ret;
ret = RESOLV_CALL( query, &query_params ); diff --git a/dlls/dnsapi/tests/query.c b/dlls/dnsapi/tests/query.c index 61b7ef093c3..51438924aa0 100644 --- a/dlls/dnsapi/tests/query.c +++ b/dlls/dnsapi/tests/query.c @@ -66,6 +66,45 @@ static void test_DnsQuery(void) DNS_RECORDW *rec, *ptr; DNS_STATUS status;
+ /* IP in name. */ + status = DnsQuery_W(L" 192.168.111.11", DNS_TYPE_A, 0, NULL, &rec, NULL); + ok(status != ERROR_SUCCESS, "got %lu.\n", status); + status = DnsQuery_W(L"192.168.111.11 ", DNS_TYPE_A, 0, NULL, &rec, NULL); + ok(status != ERROR_SUCCESS, "got %lu.\n", status); + + status = DnsQuery_W(L"192.168.111.11", DNS_TYPE_A, 0, NULL, &rec, NULL); + ok(!status, "got %lu.\n", status); + ok(rec->wType == DNS_TYPE_A, "got %#x.\n", rec->wType); + ok(rec->wDataLength == sizeof(rec->Data.A), "got %u.\n", rec->wDataLength); + ok(rec->Data.A.IpAddress == 0x0b6fa8c0, "got %#lx.\n", rec->Data.A.IpAddress); + ok(!rec->pNext, "got %p.\n", rec->pNext); + ok(rec->dwTtl == 604800, "got %lu.\n", rec->dwTtl); + ok(!wcscmp(rec->pName, L"192.168.111.11"), "got %s.\n", debugstr_w(rec->pName)); + ok(!rec->Flags.S.Section, "got %u.\n", rec->Flags.S.Section); + ok(!rec->Flags.S.Delete, "got %u.\n", rec->Flags.S.Delete); + ok(rec->Flags.S.CharSet == DnsCharSetUnicode, "got %u.\n", rec->Flags.S.CharSet); + ok(!rec->Flags.S.Unused, "got %u.\n", rec->Flags.S.Unused); + ok(rec->Flags.S.Reserved == 0x20, "got %u.\n", rec->Flags.S.Reserved); + DnsRecordListFree(rec, DnsFreeRecordList); + + status = DnsQuery_W(L"2001:db8:3333:4444:5555:6666:7777:8888", DNS_TYPE_AAAA, 0, NULL, &rec, NULL); + ok(!status, "got %lu.\n", status); + ok(rec->wType == DNS_TYPE_AAAA, "got %#x.\n", rec->wType); + ok(rec->wDataLength == sizeof(rec->Data.AAAA), "got %u.\n", rec->wDataLength); + ok(rec->Data.AAAA.Ip6Address.IP6Dword[0] == 0xb80d0120, "got %#lx.\n", rec->Data.AAAA.Ip6Address.IP6Dword[0]); + ok(rec->Data.AAAA.Ip6Address.IP6Dword[1] == 0x44443333, "got %#lx.\n", rec->Data.AAAA.Ip6Address.IP6Dword[1]); + ok(rec->Data.AAAA.Ip6Address.IP6Dword[2] == 0x66665555, "got %#lx.\n", rec->Data.AAAA.Ip6Address.IP6Dword[2]); + ok(rec->Data.AAAA.Ip6Address.IP6Dword[3] == 0x88887777, "got %#lx.\n", rec->Data.AAAA.Ip6Address.IP6Dword[3]); + ok(!rec->pNext, "got %p.\n", rec->pNext); + ok(rec->dwTtl == 604800, "got %lu.\n", rec->dwTtl); + ok(!wcscmp(rec->pName, L"2001:db8:3333:4444:5555:6666:7777:8888"), "got %s.\n", debugstr_w(rec->pName)); + ok(!rec->Flags.S.Section, "got %u.\n", rec->Flags.S.Section); + ok(!rec->Flags.S.Delete, "got %u.\n", rec->Flags.S.Delete); + ok(rec->Flags.S.CharSet == DnsCharSetUnicode, "got %u.\n", rec->Flags.S.CharSet); + ok(!rec->Flags.S.Unused, "got %u.\n", rec->Flags.S.Unused); + ok(rec->Flags.S.Reserved == 0x20, "got %u.\n", rec->Flags.S.Reserved); + DnsRecordListFree(rec, DnsFreeRecordList); + rec = NULL; status = DnsQuery_W(L"winehq.org", DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, &rec, NULL); if (status == ERROR_TIMEOUT)