https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c35ebdfeb613242eaa905…
commit c35ebdfeb613242eaa905230033712d43d8b0070
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Sun Dec 1 17:17:50 2019 +0100
Commit: Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Sun Dec 1 17:18:47 2019 +0100
[DNSRSLVR] Add support for IP6 hosts file entries
---
base/services/dnsrslvr/hostsfile.c | 201 +++++++++++++++++++------------------
1 file changed, 106 insertions(+), 95 deletions(-)
diff --git a/base/services/dnsrslvr/hostsfile.c b/base/services/dnsrslvr/hostsfile.c
index 1f12b87455f..98d39374d4e 100644
--- a/base/services/dnsrslvr/hostsfile.c
+++ b/base/services/dnsrslvr/hostsfile.c
@@ -8,11 +8,14 @@
*/
#include "precomp.h"
+#include <inaddr.h>
+#include <in6addr.h>
#define NDEBUG
#include <debug.h>
+static WCHAR szHexChar[] = L"0123456789abcdef";
static
PWSTR
@@ -50,104 +53,51 @@ AnsiToUnicode(
static
BOOL
-ParseV4Address(
- LPCSTR AddressString,
- OUT PDWORD pAddress)
+ParseIpv4Address(
+ _In_ PCSTR AddressString,
+ _Out_ PIN_ADDR pAddress)
{
- CHAR *cp;
- DWORD val, base;
- unsigned char c;
- DWORD parts[4], *pp = parts;
+ PCSTR pTerminator = NULL;
+ NTSTATUS Status;
- cp = (CHAR *)AddressString;
+ Status = RtlIpv4StringToAddressA(AddressString,
+ TRUE,
+ &pTerminator,
+ pAddress);
+ if (NT_SUCCESS(Status) && pTerminator != NULL && *pTerminator ==
'\0')
+ return TRUE;
- if (!AddressString)
- return FALSE;
-
- if (!isdigit(*cp))
- return FALSE;
-
-again:
- /*
- * Collect number up to ``.''.
- * Values are specified as for C:
- * 0x=hex, 0=octal, other=decimal.
- */
- val = 0; base = 10;
- if (*cp == '0')
- {
- if (*++cp == 'x' || *cp == 'X')
- base = 16, cp++;
- else
- base = 8;
- }
-
- while ((c = *cp))
- {
- if (isdigit(c))
- {
- val = (val * base) + (c - '0');
- cp++;
- continue;
- }
-
- if (base == 16 && isxdigit(c))
- {
- val = (val << 4) + (c + 10 - (islower(c) ? 'a' :
'A'));
- cp++;
- continue;
- }
- break;
- }
-
- if (*cp == '.')
- {
- /*
- * Internet format:
- * a.b.c.d
- */
- if (pp >= parts + 4)
- return FALSE;
- *pp++ = val;
- cp++;
- goto again;
- }
-
- /* Check for trailing characters */
- if (*cp && *cp > ' ')
- return FALSE;
-
- if (pp >= parts + 4)
- return FALSE;
-
- *pp++ = val;
- /*
- * Concoct the address according to
- * the number of parts specified.
- */
- if ((DWORD)(pp - parts) != 4)
- return FALSE;
+ return FALSE;
+}
- if (parts[0] > 0xff || parts[1] > 0xff || parts[2] > 0xff || parts[3] >
0xff)
- return FALSE;
- val = (parts[3] << 24) | (parts[2] << 16) | (parts[1] << 8) |
parts[0];
+static
+BOOL
+ParseIpv6Address(
+ _In_ LPCSTR AddressString,
+ _Out_ PIN6_ADDR pAddress)
+{
+ PCSTR pTerminator = NULL;
+ NTSTATUS Status;
- if (pAddress)
- *pAddress = val;
+ Status = RtlIpv6StringToAddressA(AddressString,
+ &pTerminator,
+ pAddress);
+ if (NT_SUCCESS(Status) && pTerminator != NULL && *pTerminator ==
'\0')
+ return TRUE;
- return TRUE;
+ return FALSE;
}
static
VOID
-AddV4HostEntries(
+AddIpv4HostEntries(
PWSTR pszHostName,
- DWORD dwIpAddress)
+ PIN_ADDR pAddress)
{
DNS_RECORDW ARecord, PtrRecord;
- WCHAR szInAddrArpaName[32];
+ WCHAR szReverseName[32];
/* Prepare the A record */
ZeroMemory(&ARecord, sizeof(DNS_RECORDW));
@@ -157,19 +107,19 @@ AddV4HostEntries(
ARecord.wDataLength = sizeof(DNS_A_DATA);
ARecord.dwTtl = 86400;
- ARecord.Data.A.IpAddress = dwIpAddress;
+ ARecord.Data.A.IpAddress = pAddress->S_un.S_addr;
- swprintf(szInAddrArpaName,
+ /* Prepare the PTR record */
+ swprintf(szReverseName,
L"%u.%u.%u.%u.in-addr.arpa",
- (dwIpAddress >> 24) & 0xFF,
- (dwIpAddress >> 16) & 0xFF,
- (dwIpAddress >> 8) & 0xFF,
- dwIpAddress & 0xFF);
+ pAddress->S_un.S_un_b.s_b4,
+ pAddress->S_un.S_un_b.s_b3,
+ pAddress->S_un.S_un_b.s_b2,
+ pAddress->S_un.S_un_b.s_b1);
- /* Prepare the PTR record */
ZeroMemory(&PtrRecord, sizeof(DNS_RECORDW));
- PtrRecord.pName = szInAddrArpaName;
+ PtrRecord.pName = szReverseName;
PtrRecord.wType = DNS_TYPE_PTR;
PtrRecord.wDataLength = sizeof(DNS_PTR_DATA);
PtrRecord.dwTtl = 86400;
@@ -181,6 +131,56 @@ AddV4HostEntries(
}
+static
+VOID
+AddIpv6HostEntries(
+ PWSTR pszHostName,
+ PIN6_ADDR pAddress)
+{
+ DNS_RECORDW AAAARecord, PtrRecord;
+ WCHAR szReverseName[80];
+ DWORD i, j, k;
+
+ /* Prepare the AAAA record */
+ ZeroMemory(&AAAARecord, sizeof(DNS_RECORDW));
+
+ AAAARecord.pName = pszHostName;
+ AAAARecord.wType = DNS_TYPE_AAAA;
+ AAAARecord.wDataLength = sizeof(DNS_AAAA_DATA);
+ AAAARecord.dwTtl = 86400;
+
+ CopyMemory(&AAAARecord.Data.AAAA.Ip6Address,
+ &pAddress->u.Byte,
+ sizeof(IN6_ADDR));
+
+ /* Prepare the PTR record */
+ ZeroMemory(szReverseName, sizeof(szReverseName));
+
+ for (i = 0; i < sizeof(IN6_ADDR); i++)
+ {
+ j = 4 * i;
+ k = sizeof(IN6_ADDR) - 1 - i;
+ szReverseName[j] = szHexChar[pAddress->u.Byte[k] & 0xF];
+ szReverseName[j + 1] = L'.';
+ szReverseName[j + 2] = szHexChar[(pAddress->u.Byte[k] >> 4) & 0xF];
+ szReverseName[j + 3] = L'.';
+ }
+ wcscat(szReverseName, L"ip6.arpa");
+
+ ZeroMemory(&PtrRecord, sizeof(DNS_RECORDW));
+
+ PtrRecord.pName = szReverseName;
+ PtrRecord.wType = DNS_TYPE_PTR;
+ PtrRecord.wDataLength = sizeof(DNS_PTR_DATA);
+ PtrRecord.dwTtl = 86400;
+
+ PtrRecord.Data.PTR.pNameHost = pszHostName;
+
+ DnsIntCacheAddEntry(&AAAARecord);
+ DnsIntCacheAddEntry(&PtrRecord);
+}
+
+
static
FILE *
OpenHostsFile(VOID)
@@ -285,7 +285,8 @@ ReadHostsFile(VOID)
CHAR szLineBuffer[512];
FILE *pHostFile = NULL;
CHAR *Ptr, *NameStart, *NameEnd, *AddressStart, *AddressEnd;
- DWORD Address;
+ struct in_addr Ipv4Address;
+ struct in6_addr Ipv6Address;
PWSTR pszHostName;
pHostFile = OpenHostsFile();
@@ -374,15 +375,25 @@ ReadHostsFile(VOID)
DPRINT("%s ==> %s\n", NameStart, AddressStart);
- if (ParseV4Address(AddressStart, &Address))
+ if (ParseIpv4Address(AddressStart, &Ipv4Address))
{
- DPRINT("IP4: %s ==> 0x%08lx\n", AddressStart, Address);
+ DPRINT("IPv4: %s\n", AddressStart);
pszHostName = AnsiToUnicode(NameStart);
if (pszHostName != NULL)
{
- AddV4HostEntries(pszHostName, Address);
+ AddIpv4HostEntries(pszHostName, &Ipv4Address);
+ HeapFree(GetProcessHeap(), 0, pszHostName);
+ }
+ }
+ else if (ParseIpv6Address(AddressStart, &Ipv6Address))
+ {
+ DPRINT("IPv6: %s\n", AddressStart);
+ pszHostName = AnsiToUnicode(NameStart);
+ if (pszHostName != NULL)
+ {
+ AddIpv6HostEntries(pszHostName, &Ipv6Address);
HeapFree(GetProcessHeap(), 0, pszHostName);
}
}