-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathDNSQuery.c
More file actions
158 lines (144 loc) · 5.43 KB
/
DNSQuery.c
File metadata and controls
158 lines (144 loc) · 5.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//https://gist.github.com/KunYi/15a71471ffcc6fb1f5f012d87dea84ea
//DNSQuery.c
// the code modify
// from https://support.microsoft.com/en-us/help/831226/how-to-use-the-dnsquery-function-to-resolve-host-names-and-host-addres
// build/testing with VisualStudio 2019 passed
// and only support IPV4
// DNSQuery.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <winsock2.h> //winsock
#include <ws2tcpip.h> //for tcpip api, inet_pton(), inet_ntop()
#include <windns.h> //DNS api's
#include <stdio.h> //standard i/o
#pragma comment(lib, "Ws2_32")
#pragma comment(lib, "Dnsapi")
// Usage of the program
void Usage(char *progname) {
fprintf(stderr,
"Usage\n%s -n [HostName|IP Address] -t [Type] -s [DnsServerIp]\n",
progname);
fprintf(stderr,
"Where:\n\t\"HostName|IP Address\" is the name or IP address of the "
"computer ");
fprintf(stderr, "of the record set being queried\n");
fprintf(stderr,
"\t\"Type\" is the type of record set to be queried A or PTR\n");
fprintf(stderr,
"\t\"DnsServerIp\"is the IP address of DNS server (in dotted decimal "
"notation) ");
fprintf(stderr, "to which the query should be sent\n");
exit(1);
}
void ReverseIP(char *pIP, size_t size) {
char seps[] = ".";
char *token;
char pIPSec[4][4];
char *pTmp = {0};
int i = 0;
token = strtok_s(pIP, seps, &pTmp);
while (token != NULL) {
/* While there are "." characters in "string" */
sprintf_s(pIPSec[i], "%s", token);
/* Get next "." character: */
token = strtok_s(NULL, seps, &pTmp);
i++;
}
sprintf_s(pIP, size, "%s.%s.%s.%s.%s", pIPSec[3], pIPSec[2], pIPSec[1], pIPSec[0],
"IN-ADDR.ARPA");
}
// the main function
int __cdecl main(int argc, char *argv[]) {
DNS_STATUS status; // Return value of DnsQuery_A() function.
PDNS_RECORD pDnsRecord; // Pointer to DNS_RECORD structure.
PIP4_ARRAY pSrvList = NULL; // Pointer to IP4_ARRAY structure.
WORD wType; // Type of the record to be queried.
char *pOwnerName = NULL; // Owner name to be queried.
char pReversedIP[255]; // Reversed IP address.
char DnsServIp[255]; // DNS server ip address.
DNS_FREE_TYPE freetype;
freetype = DnsFreeRecordListDeep;
IN_ADDR ipaddr;
if (argc > 4) {
for (int i = 1; i < argc; i++) {
if ((argv[i][0] == '-') || (argv[i][0] == '/')) {
switch (tolower(argv[i][1])) {
case 'n':
pOwnerName = argv[++i];
break;
case 't':
if (!_stricmp(argv[i + 1], "A"))
wType = DNS_TYPE_A; // Query host records to resolve a name.
else if (!_stricmp(argv[i + 1], "PTR")) {
// pOwnerName should be in "xxx.xxx.xxx.xxx" format
if (strlen(pOwnerName) <= 15) {
// You must reverse the IP address to request a Reverse Lookup
// of a host name.
sprintf_s(pReversedIP, "%s", pOwnerName);
ReverseIP(pReversedIP, sizeof(pReversedIP));
pOwnerName = pReversedIP;
wType =
DNS_TYPE_PTR; // Query PTR records to resolve an IP address
} else {
Usage(argv[0]);
}
} else
Usage(argv[0]);
i++;
break;
case 's':
// Allocate memory for IP4_ARRAY structure.
pSrvList = (PIP4_ARRAY)LocalAlloc(LPTR, sizeof(IP4_ARRAY));
if (!pSrvList) {
printf("Memory allocation failed \n");
exit(1);
}
if (argv[++i]) {
strcpy_s(DnsServIp, argv[i]);
pSrvList->AddrCount = 1;
inet_pton(AF_INET, DnsServIp, &pSrvList->AddrArray[0]); // DNS server IPv4 address
break;
}
default:
Usage(argv[0]);
break;
}
} else
Usage(argv[0]);
}
} else
Usage(argv[0]);
// Calling function DnsQuery to query Host or PTR records
status = DnsQuery(
pOwnerName, // Pointer to OwnerName.
wType, // Type of the record to be queried.
DNS_QUERY_BYPASS_CACHE, // Bypasses the resolver cache on the lookup.
pSrvList, // Contains DNS server IP address.
&pDnsRecord, // Resource record that contains the response.
NULL); // Reserved for future use.
if (status) {
if (wType == DNS_TYPE_A)
printf("Failed to query the host record for %s and the error is %d \n",
pOwnerName, status);
else
printf("Failed to query the PTR record and the error is %d \n", status);
} else {
if (wType == DNS_TYPE_A) {
char ipv4Abuff[255] = {0};
// convert the Internet network address into a string
// in Internet standard dotted format.
// for ipv4
ipaddr.S_un.S_addr = (pDnsRecord->Data.A.IpAddress);
inet_ntop(AF_INET, &ipaddr, ipv4Abuff, sizeof(ipv4Abuff));
printf("The IP address of the host %s is %s \n", pOwnerName,
ipv4Abuff);
// Free memory allocated for DNS records.
DnsRecordListFree(pDnsRecord, freetype);
} else {
printf("The host name is %s \n", (pDnsRecord->Data.PTR.pNameHost));
// Free memory allocated for DNS records.
DnsRecordListFree(pDnsRecord, freetype);
}
}
LocalFree(pSrvList);
return 0;
}