https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b0d4763f2bd41df058389…
commit b0d4763f2bd41df0583898d5a80c567204d57e5d
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Sun Oct 20 23:24:28 2019 +0200
Commit: Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Sun Oct 20 23:24:28 2019 +0200
[IPCONFIG] Implement the /flushdns option and most of the /displaydns option
---
base/applications/network/ipconfig/CMakeLists.txt | 2 +-
base/applications/network/ipconfig/ipconfig.c | 136 +++++++++++++++++++++-
2 files changed, 134 insertions(+), 4 deletions(-)
diff --git a/base/applications/network/ipconfig/CMakeLists.txt
b/base/applications/network/ipconfig/CMakeLists.txt
index d772922feed..f91e1969a28 100644
--- a/base/applications/network/ipconfig/CMakeLists.txt
+++ b/base/applications/network/ipconfig/CMakeLists.txt
@@ -1,5 +1,5 @@
add_executable(ipconfig ipconfig.c ipconfig.rc)
set_module_type(ipconfig win32cui)
-add_importlibs(ipconfig user32 iphlpapi advapi32 msvcrt kernel32)
+add_importlibs(ipconfig user32 iphlpapi dnsapi advapi32 msvcrt kernel32 ntdll)
add_cd_file(TARGET ipconfig DESTINATION reactos/system32 FOR all)
diff --git a/base/applications/network/ipconfig/ipconfig.c
b/base/applications/network/ipconfig/ipconfig.c
index af8b1467a9a..ced1de7072d 100644
--- a/base/applications/network/ipconfig/ipconfig.c
+++ b/base/applications/network/ipconfig/ipconfig.c
@@ -8,10 +8,11 @@
/*
* TODO:
* fix renew / release
- * implement flushdns, registerdns, displaydns, showclassid, setclassid
+ * implement registerdns, showclassid, setclassid
* allow globbing on adapter names
*/
+#define WIN32_NO_STATUS
#include <stdarg.h>
#include <windef.h>
#include <winbase.h>
@@ -21,6 +22,10 @@
#include <tchar.h>
#include <time.h>
#include <iphlpapi.h>
+#include <ndk/rtlfuncs.h>
+#include <inaddr.h>
+#include <windns.h>
+#include <windns_undoc.h>
#include "resource.h"
@@ -725,7 +730,132 @@ VOID Renew(LPTSTR Index)
}
}
+VOID
+FlushDns(VOID)
+{
+ _tprintf(_T("\nReactOS IP Configuration\n\n"));
+
+ if (DnsFlushResolverCache())
+ _tprintf(_T("The DNS Resolver Cache has been deleted.\n"));
+ else
+ DoFormatMessage(GetLastError());
+}
+VOID
+DisplayDns(VOID)
+{
+ PDNSCACHEENTRY DnsEntry = NULL, pThisEntry, pNextEntry;
+ PDNS_RECORDW pQueryResults, pThisRecord, pNextRecord;
+ IN_ADDR Addr4;
+ IN6_ADDR Addr6;
+ WCHAR szBuffer[48];
+ DNS_STATUS Status;
+
+ _tprintf(_T("\nReactOS IP Configuration\n\n"));
+
+ if (!DnsGetCacheDataTable(&DnsEntry))
+ {
+ DoFormatMessage(GetLastError());
+ return;
+ }
+
+ if (DnsEntry == NULL)
+ return;
+
+ pThisEntry = DnsEntry;
+ while (pThisEntry != NULL)
+ {
+ pNextEntry = pThisEntry->pNext;
+
+ pQueryResults = NULL;
+ Status = DnsQuery_W(pThisEntry->pszName,
+ pThisEntry->wType,
+ DNS_QUERY_NO_WIRE_QUERY,
+ NULL,
+ (PDNS_RECORD *)&pQueryResults,
+ NULL);
+ if (Status == 0)
+ {
+ _tprintf(_T("\t%S\n"), pThisEntry->pszName);
+ _tprintf(_T("\t----------------------------------------\n"));
+
+ pThisRecord = pQueryResults;
+ while (pThisRecord != NULL)
+ {
+ pNextRecord = pThisRecord->pNext;
+
+ _tprintf(_T("\tRecord Name . . . . . : %S\n"),
pThisRecord->pName);
+ _tprintf(_T("\tRecord Type . . . . . : %hu\n"),
pThisRecord->wType);
+ _tprintf(_T("\tTime To Live. . . . . : %lu\n"),
pThisRecord->dwTtl);
+ _tprintf(_T("\tData Length . . . . . : %hu\n"),
pThisRecord->wDataLength);
+
+ switch (pThisRecord->Flags.S.Section)
+ {
+ case DnsSectionQuestion:
+ _tprintf(_T("\tSection . . . . . . . : Question\n"));
+ break;
+
+ case DnsSectionAnswer:
+ _tprintf(_T("\tSection . . . . . . . : Answer\n"));
+ break;
+
+ case DnsSectionAuthority:
+ _tprintf(_T("\tSection . . . . . . . : Authority\n"));
+ break;
+
+ case DnsSectionAdditional:
+ _tprintf(_T("\tSection . . . . . . . :
Additional\n"));
+ break;
+ }
+
+ switch (pThisRecord->wType)
+ {
+ case DNS_TYPE_A:
+ Addr4.S_un.S_addr = pThisRecord->Data.A.IpAddress;
+ RtlIpv4AddressToStringW(&Addr4, szBuffer);
+ _tprintf(_T("\tA (Host) Record . . . : %S\n"),
szBuffer);
+ break;
+
+ case DNS_TYPE_PTR:
+ _tprintf(_T("\tPTR Record. . . . . . : %S\n"),
pThisRecord->Data.PTR.pNameHost);
+ break;
+
+ case DNS_TYPE_NS:
+ _tprintf(_T("\tNS Record . . . . . . : %S\n"),
pThisRecord->Data.NS.pNameHost);
+ break;
+
+ case DNS_TYPE_CNAME:
+ _tprintf(_T("\tCNAME Record. . . . . : %S\n"),
pThisRecord->Data.CNAME.pNameHost);
+ break;
+
+ case DNS_TYPE_AAAA:
+ RtlCopyMemory(&Addr6,
&pThisRecord->Data.AAAA.Ip6Address, sizeof(IN6_ADDR));
+ RtlIpv6AddressToStringW(&Addr6, szBuffer);
+ _tprintf(_T("\tAAAA Record . . . . . : %S\n"),
szBuffer);
+ break;
+ }
+ _tprintf(_T("\n\n"));
+
+ pThisRecord = pNextRecord;
+ }
+
+ DnsRecordListFree((PDNS_RECORD)pQueryResults, DnsFreeRecordList);
+ pQueryResults = NULL;
+ }
+ else if (Status != ERROR_SUCCESS && pThisEntry->wType != 0)
+ {
+ _tprintf(_T("\t%S\n"), pThisEntry->pszName);
+ _tprintf(_T("\t----------------------------------------\n"));
+ _tprintf(_T("\tNo records of type %hu\n\n"),
pThisEntry->wType);
+ }
+
+ if (pThisEntry->pszName)
+ LocalFree(pThisEntry->pszName);
+ LocalFree(pThisEntry);
+
+ pThisEntry = pNextEntry;
+ }
+}
VOID Usage(VOID)
{
@@ -835,11 +965,11 @@ int main(int argc, char *argv[])
else if (DoRenew)
Renew(NULL);
else if (DoFlushdns)
- _tprintf(_T("\nSorry /flushdns is not implemented yet\n"));
+ FlushDns();
else if (DoRegisterdns)
_tprintf(_T("\nSorry /registerdns is not implemented yet\n"));
else if (DoDisplaydns)
- _tprintf(_T("\nSorry /displaydns is not implemented yet\n"));
+ DisplayDns();
else
Usage();
break;