summaryrefslogtreecommitdiff
path: root/src/gns/w32nsp-resolve.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gns/w32nsp-resolve.c')
-rw-r--r--src/gns/w32nsp-resolve.c464
1 files changed, 0 insertions, 464 deletions
diff --git a/src/gns/w32nsp-resolve.c b/src/gns/w32nsp-resolve.c
deleted file mode 100644
index ad0fd3586..000000000
--- a/src/gns/w32nsp-resolve.c
+++ /dev/null
@@ -1,464 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file gns/w32nsp-resolve.c
22 * @brief W32 integration for GNS
23 * @author LRN
24 */
25/* Instead of including gnunet_common.h */
26#define GNUNET_memcpy(dst, src, n) do { if (0 != n) { (void)memcpy(dst, src, n); } } while (0)
27
28#include <ws2tcpip.h>
29#include <windows.h>
30#include <nspapi.h>
31#include <ws2spi.h>
32#include <nspapi.h>
33#include <initguid.h>
34#include "gnunet_w32nsp_lib.h"
35#include <stdio.h>
36
37typedef int (WSPAPI *LPNSPSTARTUP)(LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines);
38
39GUID host = { 0x0002a800, 0, 0, { 0xC0, 0, 0, 0, 0, 0, 0, 0x46 } };
40GUID ip4 = { 0x00090035, 0, 1, { 0xc0, 0, 0, 0, 0, 0, 0, 0x046 } };
41GUID ip6 = { 0x00090035, 0, 0x001c, { 0xc0, 0, 0, 0, 0, 0, 0, 0x046 } };
42
43DEFINE_GUID(W32_DNS, 0x22059D40, 0x7E9E, 0x11CF, 0xAE, 0x5A, 0x00, 0xAA, 0x00, 0xA7, 0x11, 0x2B);
44
45#define DEFINE_DNS_GUID(a, x) DEFINE_GUID(a, 0x00090035, 0x0000, x, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46)
46DEFINE_DNS_GUID(SVCID_DNS_TYPE_A, 0x0001);
47DEFINE_DNS_GUID(SVCID_DNS_TYPE_NS, 0x0002);
48DEFINE_DNS_GUID(SVCID_DNS_TYPE_CNAME, 0x0005);
49DEFINE_DNS_GUID(SVCID_DNS_TYPE_SOA, 0x0006);
50DEFINE_DNS_GUID(SVCID_DNS_TYPE_PTR, 0x000c);
51DEFINE_DNS_GUID(SVCID_DNS_TYPE_MX, 0x000f);
52DEFINE_DNS_GUID(SVCID_DNS_TYPE_TEXT, 0x0010);
53DEFINE_DNS_GUID(SVCID_DNS_TYPE_AAAA, 0x001c);
54DEFINE_DNS_GUID(SVCID_DNS_TYPE_SRV, 0x0021);
55DEFINE_GUID(SVCID_HOSTNAME, 0x0002a800, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
56DEFINE_GUID(SVCID_INET_HOSTADDRBYNAME, 0x0002a803, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
57
58//
59// Utility to turn a list of offsets into a list of addresses. Used
60// to convert structures returned as BLOBs.
61//
62
63VOID
64FixList(PCHAR ** List, PCHAR Base)
65{
66 if (*List)
67 {
68 PCHAR * Addr;
69
70 Addr = *List = (PCHAR *)(((DWORD)*List + Base));
71 while (*Addr)
72 {
73 *Addr = (PCHAR)(((DWORD)*Addr + Base));
74 Addr++;
75 }
76 }
77}
78
79
80//
81// Routine to convert a hostent returned in a BLOB to one with
82// usable pointers. The structure is converted in-place.
83//
84VOID
85UnpackHostEnt(struct hostent * hostent)
86{
87 PCHAR pch;
88
89 pch = (PCHAR)hostent;
90
91 if (hostent->h_name)
92 {
93 hostent->h_name = (PCHAR)((DWORD)hostent->h_name + pch);
94 }
95 FixList(&hostent->h_aliases, pch);
96 FixList(&hostent->h_addr_list, pch);
97}
98
99
100static void
101print_hostent(struct hostent *he)
102{
103 int i;
104 char **pAlias;
105
106 printf("\tOfficial name: %s\n", he->h_name);
107 for (i = 0, pAlias = he->h_aliases; *pAlias != 0; pAlias++)
108 {
109 printf("\tAlternate name #%d: %s\n", ++i, *pAlias);
110 }
111 printf("\tAddress type: ");
112 switch (he->h_addrtype)
113 {
114 case AF_INET:
115 printf("AF_INET\n");
116 break;
117
118 case AF_INET6:
119 printf("AF_INET6\n");
120 break;
121
122 case AF_NETBIOS:
123 printf("AF_NETBIOS\n");
124 break;
125
126 default:
127 printf(" %d\n", he->h_addrtype);
128 break;
129 }
130 printf("\tAddress length: %d\n", he->h_length);
131
132 if (he->h_addrtype == AF_INET)
133 {
134 struct sockaddr_in addr;
135 memset(&addr, 0, sizeof(addr));
136 addr.sin_family = AF_INET;
137 addr.sin_port = 0;
138 i = 0;
139 while (he->h_addr_list[i] != 0)
140 {
141 char buf[1024];
142 DWORD buflen = 1024;
143 addr.sin_addr = *(struct in_addr *)he->h_addr_list[i++];
144 if (NO_ERROR == WSAAddressToStringA((LPSOCKADDR)&addr, sizeof(addr), NULL, buf, &buflen))
145 printf("\tIPv4 Address #%d: %s\n", i, buf);
146 else
147 printf("\tIPv4 Address #%d: Can't convert: %lu\n", i, GetLastError());
148 }
149 }
150 else if (he->h_addrtype == AF_INET6)
151 {
152 struct sockaddr_in6 addr;
153 memset(&addr, 0, sizeof(addr));
154 addr.sin6_family = AF_INET6;
155 addr.sin6_port = 0;
156 i = 0;
157 while (he->h_addr_list[i] != 0)
158 {
159 char buf[1024];
160 DWORD buflen = 1024;
161 addr.sin6_addr = *(struct in6_addr *)he->h_addr_list[i++];
162 if (NO_ERROR == WSAAddressToStringA((LPSOCKADDR)&addr, sizeof(addr), NULL, buf, &buflen))
163 printf("\tIPv6 Address #%d: %s\n", i, buf);
164 else
165 printf("\tIPv6 Address #%d: Can't convert: %lu\n", i, GetLastError());
166 }
167 }
168}
169
170
171int
172main(int argc, char **argv)
173{
174 int ret;
175 int r = 1;
176 WSADATA wsd;
177 GUID prov;
178 GUID sc;
179 wchar_t *cmdl;
180 int wargc;
181 wchar_t **wargv;
182
183 if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
184 {
185 fprintf(stderr, "WSAStartup() failed: %lu\n", GetLastError());
186 return 5;
187 }
188
189 cmdl = GetCommandLineW();
190 if (cmdl == NULL)
191 {
192 WSACleanup();
193 return 2;
194 }
195 wargv = CommandLineToArgvW(cmdl, &wargc);
196 if (wargv == NULL)
197 {
198 WSACleanup();
199 return 3;
200 }
201 r = 4;
202
203 if (wargc == 5)
204 {
205 if (wcscmp(wargv[1], L"A") == 0)
206 sc = SVCID_DNS_TYPE_A;
207 else if (wcscmp(wargv[1], L"AAAA") == 0)
208 sc = SVCID_DNS_TYPE_AAAA;
209 else if (wcscmp(wargv[1], L"name") == 0)
210 sc = SVCID_HOSTNAME;
211 else if (wcscmp(wargv[1], L"addr") == 0)
212 sc = SVCID_INET_HOSTADDRBYNAME;
213 else
214 wargc -= 1;
215 if (wcscmp(wargv[4], L"mswdns") == 0)
216 prov = W32_DNS;
217 else if (wcscmp(wargv[4], L"gnunetdns") == 0)
218 prov = GNUNET_NAMESPACE_PROVIDER_DNS;
219 else
220 wargc -= 1;
221 }
222 else if (wargc == 3)
223 {
224 }
225 else
226 {
227 fprintf(stderr, "Usage: %S <record type> <service name> <NSP library path> <NSP id>\n"
228 "record type - one of the following: A | AAAA | name | addr\n"
229 "service name - a string to resolve; \" \" (a space) means 'blank'\n"
230 "NSP library path - path to libw32nsp\n"
231 "NSP id - one of the following: mswdns | gnunetdns\n",
232 wargv[0]);
233 }
234
235 if (wargc == 5)
236 {
237 HMODULE nsp;
238
239 nsp = LoadLibraryW(wargv[3]);
240 if (nsp == NULL)
241 {
242 fprintf(stderr, "Failed to load library `%S'\n", wargv[3]);
243 }
244 else
245 {
246 LPNSPSTARTUP startup = (LPNSPSTARTUP)GetProcAddress(nsp, "NSPStartup");
247 if (startup == NULL)
248 startup = (LPNSPSTARTUP)GetProcAddress(nsp, "NSPStartup@8");
249 if (startup != NULL)
250 {
251 NSP_ROUTINE api;
252 api.cbSize = sizeof(api);
253 ret = startup(&prov, &api);
254 if (NO_ERROR != ret)
255 fprintf(stderr, "startup failed: %lu\n", GetLastError());
256 else
257 {
258 HANDLE lookup;
259 WSAQUERYSETW search;
260 char buf[4096];
261 WSAQUERYSETW *result = (WSAQUERYSETW *)buf;
262 DWORD resultsize;
263 DWORD err;
264 memset(&search, 0, sizeof(search));
265 search.dwSize = sizeof(search);
266 search.lpszServiceInstanceName = (wcscmp(wargv[2], L" ") == 0) ? NULL : wargv[2];
267 search.lpServiceClassId = &sc;
268 search.lpNSProviderId = &prov;
269 search.dwNameSpace = NS_ALL;
270 ret = api.NSPLookupServiceBegin(&prov, &search, NULL, LUP_RETURN_ALL, &lookup);
271 if (ret != NO_ERROR)
272 {
273 fprintf(stderr, "lookup start failed\n");
274 }
275 else
276 {
277 resultsize = 4096;
278 ret = api.NSPLookupServiceNext(lookup, LUP_RETURN_ALL, &resultsize, result);
279 err = GetLastError();
280 if (ret != NO_ERROR)
281 {
282 fprintf(stderr, "lookup next failed: %lu\n", err);
283 }
284 else
285 {
286 int i;
287 printf("Got result:\n");
288 printf(" lpszServiceInstanceName: %S\n", result->lpszServiceInstanceName ? result->lpszServiceInstanceName : L"NULL");
289 if (result->lpServiceClassId)
290 printf(" lpServiceClassId: { 0x%08lX,0x%04X,0x%04X, { 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X } }\n",
291 result->lpServiceClassId->Data1, result->lpServiceClassId->Data2, result->lpServiceClassId->Data3, result->lpServiceClassId->Data4[0],
292 result->lpServiceClassId->Data4[1], result->lpServiceClassId->Data4[2], result->lpServiceClassId->Data4[3], result->lpServiceClassId->Data4[4],
293 result->lpServiceClassId->Data4[5], result->lpServiceClassId->Data4[6], result->lpServiceClassId->Data4[7]);
294 else
295 printf(" lpServiceClassId: NULL\n");
296 if (result->lpVersion)
297 printf(" lpVersion: 0x%08lX, %d\n", result->lpVersion->dwVersion, result->lpVersion->ecHow);
298 else
299 printf(" lpVersion: NULL\n");
300 printf(" lpszComment: %S\n", result->lpszComment ? result->lpszComment : L"NULL");
301 printf(" dwNameSpace: %lu\n", result->dwNameSpace);
302 if (result->lpNSProviderId)
303 printf(" lpNSProviderId: { 0x%08lX,0x%04X,0x%04X, { 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X } }\n",
304 result->lpNSProviderId->Data1, result->lpNSProviderId->Data2, result->lpNSProviderId->Data3, result->lpNSProviderId->Data4[0],
305 result->lpNSProviderId->Data4[1], result->lpNSProviderId->Data4[2], result->lpNSProviderId->Data4[3], result->lpNSProviderId->Data4[4],
306 result->lpNSProviderId->Data4[5], result->lpNSProviderId->Data4[6], result->lpNSProviderId->Data4[7]);
307 else
308 printf(" lpNSProviderId: NULL\n");
309 printf(" lpszContext: %S\n", result->lpszContext ? result->lpszContext : L"NULL");
310 printf(" dwNumberOfProtocols: %lu\n", result->dwNumberOfProtocols);
311 printf(" lpszQueryString: %S\n", result->lpszQueryString ? result->lpszQueryString : L"NULL");
312 printf(" dwNumberOfCsAddrs: %lu\n", result->dwNumberOfCsAddrs);
313 for (i = 0; i < result->dwNumberOfCsAddrs; i++)
314 {
315 switch (result->lpcsaBuffer[i].iSocketType)
316 {
317 case SOCK_STREAM:
318 printf(" %d: iSocketType = SOCK_STREAM\n", i);
319 break;
320
321 case SOCK_DGRAM:
322 printf(" %d: iSocketType = SOCK_DGRAM\n", i);
323 break;
324
325 default:
326 printf(" %d: iSocketType = %d\n", i, result->lpcsaBuffer[i].iSocketType);
327 }
328 switch (result->lpcsaBuffer[i].iProtocol)
329 {
330 case IPPROTO_TCP:
331 printf(" %d: iProtocol = IPPROTO_TCP\n", i);
332 break;
333
334 case IPPROTO_UDP:
335 printf(" %d: iProtocol = IPPROTO_UDP\n", i);
336 break;
337
338 default:
339 printf(" %d: iProtocol = %d\n", i, result->lpcsaBuffer[i].iProtocol);
340 }
341 switch (result->lpcsaBuffer[i].LocalAddr.lpSockaddr->sa_family)
342 {
343 case AF_INET:
344 printf(" %d: loc family = AF_INET\n", i);
345 break;
346
347 case AF_INET6:
348 printf(" %d: loc family = AF_INET6\n", i);
349 break;
350
351 default:
352 printf(" %d: loc family = %hu\n", i, result->lpcsaBuffer[i].LocalAddr.lpSockaddr->sa_family);
353 }
354 switch (result->lpcsaBuffer[i].RemoteAddr.lpSockaddr->sa_family)
355 {
356 case AF_INET:
357 printf(" %d: rem family = AF_INET\n", i);
358 break;
359
360 case AF_INET6:
361 printf(" %d: rem family = AF_INET6\n", i);
362 break;
363
364 default:
365 printf(" %d: rem family = %hu\n", i, result->lpcsaBuffer[i].RemoteAddr.lpSockaddr->sa_family);
366 }
367 char buf[1024];
368 DWORD buflen = 1024;
369 if (NO_ERROR == WSAAddressToStringA(result->lpcsaBuffer[i].LocalAddr.lpSockaddr, result->lpcsaBuffer[i].LocalAddr.iSockaddrLength, NULL, buf, &buflen))
370 printf("\tLocal Address #%d: %s\n", i, buf);
371 else
372 printf("\tLocal Address #%d: Can't convert: %lu\n", i, GetLastError());
373 buflen = 1024;
374 if (NO_ERROR == WSAAddressToStringA(result->lpcsaBuffer[i].RemoteAddr.lpSockaddr, result->lpcsaBuffer[i].RemoteAddr.iSockaddrLength, NULL, buf, &buflen))
375 printf("\tRemote Address #%d: %s\n", i, buf);
376 else
377 printf("\tRemote Address #%d: Can't convert: %lu\n", i, GetLastError());
378 }
379 printf(" dwOutputFlags: 0x%08lX\n", result->dwOutputFlags);
380 printf(" lpBlob: 0x%p\n", result->lpBlob);
381 if (result->lpBlob)
382 {
383 struct hostent *he = malloc(result->lpBlob->cbSize);
384 if (he != NULL)
385 {
386 GNUNET_memcpy(he, result->lpBlob->pBlobData, result->lpBlob->cbSize);
387 UnpackHostEnt(he);
388 print_hostent(he);
389 free(he);
390 }
391 }
392 }
393 ret = api.NSPLookupServiceEnd(lookup);
394 if (ret != NO_ERROR)
395 printf("NSPLookupServiceEnd() failed: %lu\n", GetLastError());
396 }
397 api.NSPCleanup(&prov);
398 }
399 }
400 FreeLibrary(nsp);
401 }
402 }
403 else if (wargc == 3)
404 {
405 int s;
406 ADDRINFOW hints;
407 ADDRINFOW *result;
408 ADDRINFOW *pos;
409
410 memset(&hints, 0, sizeof(struct addrinfo));
411 hints.ai_family = AF_UNSPEC;
412 hints.ai_socktype = SOCK_STREAM;
413
414 if (0 != (s = GetAddrInfoW(wargv[2], NULL, &hints, &result)))
415 {
416 fprintf(stderr, "Cound not resolve `%S' using GetAddrInfoW: %lu\n",
417 wargv[2], GetLastError());
418 }
419 else
420 {
421 for (pos = result; pos != NULL; pos = pos->ai_next)
422 {
423 wchar_t tmpbuf[1024];
424 DWORD buflen = 1024;
425 if (0 == WSAAddressToStringW(pos->ai_addr, pos->ai_addrlen, NULL, tmpbuf, &buflen))
426 fprintf(stderr, "Result:\n"
427 " flags: 0x%X\n"
428 " family: 0x%X\n"
429 " socktype: 0x%X\n"
430 " protocol: 0x%X\n"
431 " addrlen: %u\n"
432 " addr: %S\n"
433 " canonname: %S\n",
434 pos->ai_flags,
435 pos->ai_family,
436 pos->ai_socktype,
437 pos->ai_protocol,
438 pos->ai_addrlen,
439 tmpbuf,
440 pos->ai_canonname);
441 else
442 fprintf(stderr, "Result:\n"
443 " flags: 0x%X\n"
444 " family: 0x%X\n"
445 " socktype: 0x%X\n"
446 " protocol: 0x%X\n"
447 " addrlen: %u\n"
448 " addr: %S\n"
449 " canonname: %S\n",
450 pos->ai_flags,
451 pos->ai_family,
452 pos->ai_socktype,
453 pos->ai_protocol,
454 pos->ai_addrlen,
455 L"<can't stringify>",
456 pos->ai_canonname);
457 }
458 if (NULL != result)
459 FreeAddrInfoW(result);
460 }
461 }
462 WSACleanup();
463 return r;
464}