-fix
[oweals/gnunet.git] / src / gns / w32nsp-resolve.c
1 #define INITGUID\r
2 #include <windows.h>\r
3 #include <nspapi.h>\r
4 #include <ws2spi.h>\r
5 #include <nspapi.h>\r
6 #include <ws2tcpip.h>\r
7 #include "gnunet_w32nsp_lib.h"\r
8 #include <stdio.h>\r
9 \r
10 typedef int (WSPAPI *LPNSPSTARTUP) (LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines);\r
11 \r
12 GUID host = {0x0002a800,0,0,{ 0xC0,0,0,0,0,0,0,0x46 }};\r
13 GUID ip4 = {0x00090035,0,1,{ 0xc0,0,0,0,0,0,0,0x046}}; \r
14 GUID ip6 = {0x00090035,0,0x001c, { 0xc0,0,0,0,0,0,0,0x046}};\r
15 \r
16 DEFINE_GUID(W32_DNS, 0x22059D40, 0x7E9E, 0x11CF, 0xAE, 0x5A, 0x00, 0xAA, 0x00, 0xA7, 0x11, 0x2B);\r
17 \r
18 #define DEFINE_DNS_GUID(a,x) DEFINE_GUID(a, 0x00090035, 0x0000, x, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46)
19 DEFINE_DNS_GUID(SVCID_DNS_TYPE_A, 0x0001);
20 DEFINE_DNS_GUID(SVCID_DNS_TYPE_NS, 0x0002);
21 DEFINE_DNS_GUID(SVCID_DNS_TYPE_CNAME, 0x0005);
22 DEFINE_DNS_GUID(SVCID_DNS_TYPE_SOA, 0x0006);
23 DEFINE_DNS_GUID(SVCID_DNS_TYPE_PTR, 0x000c);
24 DEFINE_DNS_GUID(SVCID_DNS_TYPE_MX, 0x000f);
25 DEFINE_DNS_GUID(SVCID_DNS_TYPE_TEXT, 0x0010);
26 DEFINE_DNS_GUID(SVCID_DNS_TYPE_AAAA, 0x001c);
27 DEFINE_DNS_GUID(SVCID_DNS_TYPE_SRV, 0x0021);
28 DEFINE_GUID(SVCID_HOSTNAME, 0x0002a800, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
29 DEFINE_GUID(SVCID_INET_HOSTADDRBYNAME, 0x0002a803, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
30 \r
31 //\r
32 // Utility to turn a list of offsets into a list of addresses. Used\r
33 // to convert structures returned as BLOBs.\r
34 //\r
35 \r
36 VOID FixList(PCHAR ** List, PCHAR Base)\r
37 {\r
38     if(*List)\r
39     {\r
40         PCHAR * Addr;\r
41 \r
42         Addr = *List = (PCHAR *)( ((DWORD)*List + Base) );\r
43         while(*Addr)\r
44         {\r
45             *Addr = (PCHAR)(((DWORD)*Addr + Base));\r
46             Addr++;\r
47         }\r
48     }\r
49 }\r
50 \r
51 \r
52 //\r
53 // Routine to convert a hostent returned in a BLOB to one with\r
54 // usable pointers. The structure is converted in-place.\r
55 //\r
56 VOID UnpackHostEnt(struct hostent * hostent)\r
57 {\r
58      PCHAR pch;\r
59 \r
60      pch = (PCHAR)hostent;\r
61 \r
62      if(hostent->h_name)\r
63      {\r
64          hostent->h_name = (PCHAR)((DWORD)hostent->h_name + pch);\r
65      }\r
66      FixList(&hostent->h_aliases, pch);\r
67      FixList(&hostent->h_addr_list, pch);\r
68 }\r
69 \r
70 void\r
71 print_hostent (struct hostent *he)\r
72 {\r
73   int i;\r
74   char **pAlias;\r
75   printf("\tOfficial name: %s\n", he->h_name);\r
76   for (pAlias = he->h_aliases; *pAlias != 0; pAlias++) {\r
77       printf("\tAlternate name #%d: %s\n", ++i, *pAlias);\r
78   }\r
79   printf("\tAddress type: ");\r
80   switch (he->h_addrtype) {\r
81   case AF_INET:\r
82       printf("AF_INET\n");\r
83       break;\r
84   case AF_INET6:\r
85       printf("AF_INET6\n");\r
86       break;\r
87   case AF_NETBIOS:\r
88       printf("AF_NETBIOS\n");\r
89       break;\r
90   default:\r
91       printf(" %d\n", he->h_addrtype);\r
92       break;\r
93   }\r
94   printf("\tAddress length: %d\n", he->h_length);\r
95 \r
96   if (he->h_addrtype == AF_INET) {\r
97     struct sockaddr_in addr;\r
98     memset (&addr, 0, sizeof (addr));\r
99     addr.sin_family = AF_INET;\r
100     addr.sin_port = 0;\r
101     i = 0;\r
102     while (he->h_addr_list[i] != 0) {\r
103       char buf[1024];\r
104       DWORD buflen = 1024;\r
105       addr.sin_addr = *(struct in_addr *) he->h_addr_list[i++];\r
106       if (NO_ERROR == WSAAddressToStringA ((LPSOCKADDR) &addr, sizeof (addr), NULL, buf, &buflen))\r
107         printf("\tIPv4 Address #%d: %s\n", i, buf);\r
108       else\r
109         printf("\tIPv4 Address #%d: Can't convert: %lu\n", i, GetLastError ());\r
110     }\r
111   } else if (he->h_addrtype == AF_INET6) {\r
112     struct sockaddr_in6 addr;\r
113     memset (&addr, 0, sizeof (addr));\r
114     addr.sin6_family = AF_INET6;\r
115     addr.sin6_port = 0;\r
116     i = 0;\r
117     while (he->h_addr_list[i] != 0) {\r
118       char buf[1024];\r
119       DWORD buflen = 1024;\r
120       addr.sin6_addr = *(struct in6_addr *) he->h_addr_list[i++];\r
121       if (NO_ERROR == WSAAddressToStringA ((LPSOCKADDR) &addr, sizeof (addr), NULL, buf, &buflen))\r
122         printf("\tIPv6 Address #%d: %s\n", i, buf);\r
123       else\r
124         printf("\tIPv6 Address #%d: Can't convert: %lu\n", i, GetLastError ());\r
125     }\r
126   }\r
127 }\r
128 \r
129 int\r
130 main (int argc, char **argv)\r
131 {\r
132   int ret;\r
133   int r = 1;\r
134   WSADATA wsd;\r
135   GUID *prov = NULL;\r
136   GUID *sc = NULL;\r
137   wchar_t *cmdl;\r
138   int wargc;\r
139   wchar_t **wargv;\r
140 \r
141   if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)\r
142   {\r
143     fprintf (stderr, "WSAStartup() failed: %lu\n", GetLastError());\r
144     return 5;\r
145   }\r
146 \r
147   cmdl = GetCommandLineW ();\r
148   if (cmdl == NULL)\r
149   {\r
150     WSACleanup();\r
151     return 2;\r
152   }\r
153   wargv = CommandLineToArgvW (cmdl, &wargc);\r
154   if (wargv == NULL)\r
155   {\r
156     WSACleanup();\r
157     return 3;\r
158   }\r
159   r = 4;\r
160 \r
161   if (wargc == 5)\r
162   {\r
163     if (wcscmp (wargv[1], L"A") == 0)\r
164       sc = &SVCID_DNS_TYPE_A;\r
165     else if (wcscmp (wargv[1], L"AAAA") == 0)\r
166       sc = &SVCID_DNS_TYPE_AAAA;\r
167     else if (wcscmp (wargv[1], L"name") == 0)\r
168       sc = &SVCID_HOSTNAME;\r
169     else if (wcscmp (wargv[1], L"addr") == 0)\r
170       sc = &SVCID_INET_HOSTADDRBYNAME;\r
171     else\r
172       wargc -= 1;\r
173     if (wcscmp (wargv[4], L"mswdns") == 0)\r
174       prov = &W32_DNS;\r
175     else if (wcscmp (wargv[4], L"gnunetdns") == 0)\r
176       prov = &GNUNET_NAMESPACE_PROVIDER_DNS;\r
177     else\r
178       wargc -= 1;\r
179   }\r
180 \r
181   if (wargc == 5)\r
182   {\r
183     HMODULE nsp;\r
184    \r
185     nsp = LoadLibraryW (wargv[3]);\r
186     if (nsp == NULL)\r
187     {\r
188       fprintf (stderr, "Failed to load library `%S'\n", wargv[3]);\r
189     }\r
190     else\r
191     {\r
192       LPNSPSTARTUP startup = (LPNSPSTARTUP) GetProcAddress (nsp, "NSPStartup");\r
193       if (startup != NULL)\r
194       {\r
195         NSP_ROUTINE api;\r
196         ret = startup (prov, &api);\r
197         if (NO_ERROR != ret)\r
198           fprintf (stderr, "startup failed\n");\r
199         else\r
200         {\r
201           HANDLE lookup;\r
202           WSAQUERYSETW search;\r
203           char buf[4096];\r
204           WSAQUERYSETW *result = (WSAQUERYSETW *) buf;\r
205           DWORD resultsize;\r
206           DWORD err;\r
207           memset (&search, 0, sizeof (search));\r
208           search.dwSize = sizeof (search);\r
209           search.lpszServiceInstanceName = (wcscmp (wargv[2], L" ") == 0) ? NULL : wargv[2];\r
210           search.lpServiceClassId = sc;\r
211           search.lpNSProviderId = prov;\r
212           search.dwNameSpace = NS_ALL;\r
213           ret = api.NSPLookupServiceBegin (prov, &search, NULL, LUP_RETURN_ALL, &lookup);\r
214           if (ret != NO_ERROR)\r
215           {\r
216             fprintf (stderr, "lookup start failed\n");\r
217           }\r
218           else\r
219           {\r
220             resultsize = 4096;\r
221             ret = api.NSPLookupServiceNext (lookup, LUP_RETURN_ALL, &resultsize, result);\r
222             err = GetLastError ();\r
223             if (ret != NO_ERROR)\r
224             {\r
225               fprintf (stderr, "lookup next failed\n");\r
226             }\r
227             else\r
228             {\r
229               int i;\r
230               printf ("Got result:\n");\r
231               printf ("  lpszServiceInstanceName: %S\n", result->lpszServiceInstanceName ? result->lpszServiceInstanceName : L"NULL");\r
232               if (result->lpServiceClassId)\r
233                 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",\r
234                     result->lpServiceClassId->Data1, result->lpServiceClassId->Data2, result->lpServiceClassId->Data3, result->lpServiceClassId->Data4[0],\r
235                     result->lpServiceClassId->Data4[1], result->lpServiceClassId->Data4[2], result->lpServiceClassId->Data4[3], result->lpServiceClassId->Data4[4],\r
236                     result->lpServiceClassId->Data4[5], result->lpServiceClassId->Data4[6], result->lpServiceClassId->Data4[7]);\r
237               else\r
238                 printf ("  lpServiceClassId:        NULL\n");\r
239               if (result->lpVersion)\r
240                 printf ("  lpVersion:               0x%08lX, %d\n", result->lpVersion->dwVersion, result->lpVersion->ecHow);\r
241               else\r
242                 printf ("  lpVersion:               NULL\n");\r
243               printf ("  lpszComment:             %S\n", result->lpszComment ? result->lpszComment : L"NULL");\r
244               printf ("  dwNameSpace:             %lu\n", result->dwNameSpace);\r
245               if (result->lpNSProviderId)\r
246                 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",\r
247                     result->lpNSProviderId->Data1, result->lpNSProviderId->Data2, result->lpNSProviderId->Data3, result->lpNSProviderId->Data4[0],\r
248                     result->lpNSProviderId->Data4[1], result->lpNSProviderId->Data4[2], result->lpNSProviderId->Data4[3], result->lpNSProviderId->Data4[4],\r
249                     result->lpNSProviderId->Data4[5], result->lpNSProviderId->Data4[6], result->lpNSProviderId->Data4[7]);\r
250               else\r
251                 printf ("  lpNSProviderId:          NULL\n");\r
252               printf ("  lpszContext:             %S\n", result->lpszContext ? result->lpszContext : L"NULL");\r
253               printf ("  dwNumberOfProtocols:     %lu\n", result->dwNumberOfProtocols);\r
254               printf ("  lpszQueryString:         %S\n", result->lpszQueryString ? result->lpszQueryString : L"NULL");\r
255               printf ("  dwNumberOfCsAddrs:       %lu\n", result->dwNumberOfCsAddrs);\r
256               for (i = 0; i < result->dwNumberOfCsAddrs; i++)\r
257               {\r
258                 switch (result->lpcsaBuffer[i].iSocketType)\r
259                 {\r
260                 case SOCK_STREAM:\r
261                   printf ("    %d: iSocketType = SOCK_STREAM\n", i);\r
262                   break;\r
263                 case SOCK_DGRAM:\r
264                   printf ("    %d: iSocketType = SOCK_DGRAM\n", i);\r
265                   break;\r
266                 default:\r
267                   printf ("    %d: iSocketType = %d\n", i, result->lpcsaBuffer[i].iSocketType);\r
268                 }\r
269                 switch (result->lpcsaBuffer[i].iProtocol)\r
270                 {\r
271                 case IPPROTO_TCP:\r
272                   printf ("    %d: iProtocol   = IPPROTO_TCP\n", i);\r
273                   break;\r
274                 case IPPROTO_UDP:\r
275                   printf ("    %d: iProtocol   = IPPROTO_UDP\n", i);\r
276                   break;\r
277                 default:\r
278                   printf ("    %d: iProtocol   = %d\n", i, result->lpcsaBuffer[i].iProtocol);\r
279                 }\r
280                 switch (result->lpcsaBuffer[i].LocalAddr.lpSockaddr->sa_family)\r
281                 {\r
282                 case AF_INET:\r
283                   printf ("    %d: loc family  = AF_INET\n", i);\r
284                   break;\r
285                 case AF_INET6:\r
286                   printf ("    %d: loc family  = AF_INET6\n", i);\r
287                   break;\r
288                 default:\r
289                   printf ("    %d: loc family  = %hu\n", i, result->lpcsaBuffer[i].LocalAddr.lpSockaddr->sa_family);\r
290                 }\r
291                 switch (result->lpcsaBuffer[i].RemoteAddr.lpSockaddr->sa_family)\r
292                 {\r
293                 case AF_INET:\r
294                   printf ("    %d: rem family  = AF_INET\n", i);\r
295                   break;\r
296                 case AF_INET6:\r
297                   printf ("    %d: rem family  = AF_INET6\n", i);\r
298                   break;\r
299                 default:\r
300                   printf ("    %d: rem family = %hu\n", i, result->lpcsaBuffer[i].RemoteAddr.lpSockaddr->sa_family);\r
301                 }\r
302                 char buf[1024];\r
303                 DWORD buflen = 1024;\r
304                 if (NO_ERROR == WSAAddressToStringA (result->lpcsaBuffer[i].LocalAddr.lpSockaddr, result->lpcsaBuffer[i].LocalAddr.iSockaddrLength, NULL, buf, &buflen))\r
305                   printf("\tLocal Address #%d: %s\n", i, buf);\r
306                 else\r
307                   printf("\tLocal Address #%d: Can't convert: %lu\n", i, GetLastError ());\r
308                 buflen = 1024;\r
309                 if (NO_ERROR == WSAAddressToStringA (result->lpcsaBuffer[i].RemoteAddr.lpSockaddr, result->lpcsaBuffer[i].RemoteAddr.iSockaddrLength, NULL, buf, &buflen))\r
310                   printf("\tRemote Address #%d: %s\n", i, buf);\r
311                 else\r
312                   printf("\tRemote Address #%d: Can't convert: %lu\n", i, GetLastError ());\r
313               }\r
314               printf ("  dwOutputFlags:           0x%08lX\n", result->dwOutputFlags);\r
315               printf ("  lpBlob:                  0x%p\n", result->lpBlob);\r
316               if (result->lpBlob)\r
317               {\r
318                 struct hostent *he = malloc (result->lpBlob->cbSize);\r
319                 if (he != NULL)\r
320                 {\r
321                   memcpy (he, result->lpBlob->pBlobData, result->lpBlob->cbSize);\r
322                   UnpackHostEnt (he);\r
323                   print_hostent (he);\r
324                   free (he);\r
325                 }\r
326               }\r
327             }\r
328             ret = api.NSPLookupServiceEnd (lookup);\r
329             if (ret != NO_ERROR)\r
330               printf ("NSPLookupServiceEnd() failed: %lu\n", GetLastError ());\r
331           }\r
332           api.NSPCleanup (prov);\r
333         }\r
334       }\r
335       FreeLibrary (nsp);\r
336     }\r
337   }\r
338   WSACleanup();\r
339   return r;\r
340 }