diff options
Diffstat (limited to 'src/gns/w32nsp-resolve.c')
-rw-r--r-- | src/gns/w32nsp-resolve.c | 464 |
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 | |||
37 | typedef int (WSPAPI *LPNSPSTARTUP)(LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines); | ||
38 | |||
39 | GUID host = { 0x0002a800, 0, 0, { 0xC0, 0, 0, 0, 0, 0, 0, 0x46 } }; | ||
40 | GUID ip4 = { 0x00090035, 0, 1, { 0xc0, 0, 0, 0, 0, 0, 0, 0x046 } }; | ||
41 | GUID ip6 = { 0x00090035, 0, 0x001c, { 0xc0, 0, 0, 0, 0, 0, 0, 0x046 } }; | ||
42 | |||
43 | DEFINE_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) | ||
46 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_A, 0x0001); | ||
47 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_NS, 0x0002); | ||
48 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_CNAME, 0x0005); | ||
49 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_SOA, 0x0006); | ||
50 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_PTR, 0x000c); | ||
51 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_MX, 0x000f); | ||
52 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_TEXT, 0x0010); | ||
53 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_AAAA, 0x001c); | ||
54 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_SRV, 0x0021); | ||
55 | DEFINE_GUID(SVCID_HOSTNAME, 0x0002a800, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); | ||
56 | DEFINE_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 | |||
63 | VOID | ||
64 | FixList(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 | // | ||
84 | VOID | ||
85 | UnpackHostEnt(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 | |||
100 | static void | ||
101 | print_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 | |||
171 | int | ||
172 | main(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 = ≻ | ||
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 | } | ||