ReactOS  0.4.12-dev-102-g4b7f1e0
nslookup.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS nslookup utility
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: base/applications/network/nslookup/nslookup.c
5  * PURPOSE: Perform DNS lookups
6  * COPYRIGHT: Copyright 2009 Lucas Suggs <lucas.suggs@gmail.com>
7  */
8 
9 #include "nslookup.h"
10 
11 #include <winbase.h>
12 #include <iphlpapi.h>
13 
17 
18 void PrintState()
19 {
20  _tprintf( _T("Default Server: (null)\n\n") );
21  _tprintf( _T("Set options:\n") );
22 
23  _tprintf( _T(" ") );
24  if( !State.debug ) _tprintf( _T("no") );
25  _tprintf( _T("debug\n") );
26 
27  _tprintf( _T(" ") );
28  if( !State.defname ) _tprintf( _T("no") );
29  _tprintf( _T("defname\n") );
30 
31  _tprintf( _T(" ") );
32  if( !State.search ) _tprintf( _T("no") );
33  _tprintf( _T("search\n") );
34 
35  _tprintf( _T(" ") );
36  if( !State.recurse ) _tprintf( _T("no") );
37  _tprintf( _T("recurse\n") );
38 
39  _tprintf( _T(" ") );
40  if( !State.d2 ) _tprintf( _T("no") );
41  _tprintf( _T("d2\n") );
42 
43  _tprintf( _T(" ") );
44  if( !State.vc ) _tprintf( _T("no") );
45  _tprintf( _T("vc\n") );
46 
47  _tprintf( _T(" ") );
48  if( !State.ignoretc ) _tprintf( _T("no") );
49  _tprintf( _T("ignoretc\n") );
50 
51  _tprintf( _T(" port=%d\n"), State.port );
52  _tprintf( _T(" type=%s\n"), State.type );
53  _tprintf( _T(" class=%s\n"), State.Class );
54  _tprintf( _T(" timeout=%d\n"), (int)State.timeout );
55  _tprintf( _T(" retry=%d\n"), (int)State.retry );
56  _tprintf( _T(" root=%s\n"), State.root );
57  _tprintf( _T(" domain=%s\n"), State.domain );
58 
59  _tprintf( _T(" ") );
60  if( !State.MSxfr ) _tprintf( _T("no") );
61  _tprintf( _T("MSxfr\n") );
62 
63  _tprintf( _T(" IXFRversion=%d\n"), (int)State.ixfrver );
64 
65  _tprintf( _T(" srchlist=%s\n\n"), State.srchlist[0] );
66 }
67 
68 void PrintUsage()
69 {
70  _tprintf( _T("Usage:\n"
71  " nslookup [-opt ...] # interactive mode using"
72  " default server\n nslookup [-opt ...] - server #"
73  " interactive mode using 'server'\n nslookup [-opt ...]"
74  " host # just look up 'host' using default server\n"
75  " nslookup [-opt ...] host server # just look up 'host'"
76  " using 'server'\n") );
77 }
78 
80 {
81  /* Needed to issue DNS packets and parse them. */
82  PCHAR Buffer = NULL, RecBuffer = NULL;
83  CHAR pResolve[256];
84  ULONG BufferLength = 0, RecBufferLength = 512;
85  int i = 0, j = 0, k = 0, d = 0;
86  BOOL bOk = FALSE;
87 
88  /* Makes things easier when parsing the response packet. */
89  USHORT NumQuestions;
90  USHORT Type;
91 
92  if( (strlen( pAddr ) + 1) > 255 ) return FALSE;
93 
94  Type = TYPE_A;
95  if( IsValidIP( pAddr ) ) Type = TYPE_PTR;
96 
97  /* If it's a PTR lookup then append the ARPA sig to the end. */
98  if( Type == TYPE_PTR )
99  {
100  ReverseIP( pAddr, pResolve );
101  strcat( pResolve, ARPA_SIG );
102  }
103  else
104  {
105  strcpy( pResolve, pAddr );
106  }
107 
108  /* Base header length + length of QNAME + length of QTYPE and QCLASS */
109  BufferLength = 12 + (strlen( pResolve ) + 2) + 4;
110 
111  /* Allocate memory for the buffer. */
112  Buffer = HeapAlloc( ProcessHeap, 0, BufferLength );
113  if( !Buffer )
114  {
115  _tprintf( _T("ERROR: Out of memory\n") );
116  goto cleanup;
117  }
118 
119  /* Allocate the receiving buffer. */
120  RecBuffer = HeapAlloc( ProcessHeap, 0, RecBufferLength );
121  if( !RecBuffer )
122  {
123  _tprintf( _T("ERROR: Out of memory\n") );
124  goto cleanup;
125  }
126 
127  /* Insert the ID field. */
128  ((PSHORT)&Buffer[i])[0] = htons( RequestID );
129  i += 2;
130 
131  /* Bits 0-7 of the second 16 are all 0, except for when recursion is
132  desired. */
133  Buffer[i] = 0x00;
134  if( State.recurse) Buffer[i] |= 0x01;
135  i += 1;
136 
137  /* Bits 8-15 of the second 16 are 0 for a query. */
138  Buffer[i] = 0x00;
139  i += 1;
140 
141  /* Only 1 question. */
142  ((PSHORT)&Buffer[i])[0] = htons( 1 );
143  i += 2;
144 
145  /* We aren't sending a response, so 0 out the rest of the header. */
146  Buffer[i] = 0x00;
147  Buffer[i + 1] = 0x00;
148  Buffer[i + 2] = 0x00;
149  Buffer[i + 3] = 0x00;
150  Buffer[i + 4] = 0x00;
151  Buffer[i + 5] = 0x00;
152  i += 6;
153 
154  /* Walk through the query address. Split each section delimited by '.'.
155  Format of the QNAME section is length|data, etc. Last one is null */
156  j = i;
157  i += 1;
158 
159  for( k = 0; k < strlen( pResolve ); k += 1 )
160  {
161  if( pResolve[k] != '.' )
162  {
163  Buffer[i] = pResolve[k];
164  i += 1;
165  }
166  else
167  {
168  Buffer[j] = (i - j) - 1;
169  j = i;
170  i += 1;
171  }
172  }
173 
174  Buffer[j] = (i - j) - 1;
175  Buffer[i] = 0x00;
176  i += 1;
177 
178  /* QTYPE */
179  ((PSHORT)&Buffer[i])[0] = htons( Type );
180  i += 2;
181 
182  /* QCLASS */
183  ((PSHORT)&Buffer[i])[0] = htons( CLASS_IN );
184 
185  /* Ship the request off to the DNS server. */
186  bOk = SendRequest( Buffer,
187  BufferLength,
188  RecBuffer,
189  &RecBufferLength );
190  if( !bOk ) goto cleanup;
191 
192  /* Start parsing the received packet. */
193  NumQuestions = ntohs( ((PSHORT)&RecBuffer[4])[0] );
194 
195  k = 12;
196 
197  /* We don't care about the questions section, blow through it. */
198  if( NumQuestions )
199  {
200  for( i = 0; i < NumQuestions; i += 1 )
201  {
202  /* Quick way to skip the domain name section. */
203  k += ExtractName( RecBuffer, pResult, k, 0 );
204  k += 4;
205  }
206  }
207 
208  /* Skip the answer name. */
209  k += ExtractName( RecBuffer, pResult, k, 0 );
210 
211  Type = ntohs( ((PUSHORT)&RecBuffer[k])[0] );
212  k += 8;
213 
214  d = ntohs( ((PUSHORT)&RecBuffer[k])[0] );
215  k += 2;
216 
217  if( TYPE_PTR == Type )
218  {
219  k += ExtractName( RecBuffer, pResult, k, d );
220  }
221  else if( TYPE_A == Type )
222  {
223  k += ExtractIP( RecBuffer, pResult, k );
224  }
225 
226 cleanup:
227  /* Free memory. */
228  if( Buffer ) HeapFree( ProcessHeap, 0, Buffer );
229  if( RecBuffer ) HeapFree( ProcessHeap, 0, RecBuffer );
230 
231  RequestID += 1;
232 
233  return bOk;
234 }
235 
236 void PerformLookup( PCHAR pAddr )
237 {
238  /* Needed to issue DNS packets and parse them. */
239  PCHAR Buffer = NULL, RecBuffer = NULL;
240  CHAR pResolve[256];
241  CHAR pResult[256];
242  ULONG BufferLength = 0, RecBufferLength = 512;
243  int i = 0, j = 0, k = 0, d = 0;
244  BOOL bOk = FALSE;
245 
246  /* Makes things easier when parsing the response packet. */
247  UCHAR Header2;
248  USHORT NumQuestions;
249  USHORT NumAnswers;
250  USHORT NumAuthority;
251  USHORT Type;
252 
253  if( (strlen( pAddr ) + 1) > 255 ) return;
254 
255  _tprintf( _T("Server: %s\n"), State.DefaultServer );
256  _tprintf( _T("Address: %s\n\n"), State.DefaultServerAddress );
257 
258  if( !strcmp( TypeA, State.type )
259  || !strcmp( TypeAAAA, State.type )
260  || !strcmp( TypeBoth, State.type ) )
261  {
262  Type = TYPE_A;
263  if( IsValidIP( pAddr ) ) Type = TYPE_PTR;
264  }
265  else
266  Type = TypeNametoTypeID( State.type );
267 
268  /* If it's a PTR lookup then append the ARPA sig to the end. */
269  if( (Type == TYPE_PTR) && IsValidIP( pAddr ) )
270  {
271  ReverseIP( pAddr, pResolve );
272  strcat( pResolve, ARPA_SIG );
273  }
274  else
275  {
276  strcpy( pResolve, pAddr );
277  }
278 
279  /* Base header length + length of QNAME + length of QTYPE and QCLASS */
280  BufferLength = 12 + (strlen( pResolve ) + 2) + 4;
281 
282  /* Allocate memory for the buffer. */
283  Buffer = HeapAlloc( ProcessHeap, 0, BufferLength );
284  if( !Buffer )
285  {
286  _tprintf( _T("ERROR: Out of memory\n") );
287  goto cleanup;
288  }
289 
290  /* Allocate memory for the return buffer. */
291  RecBuffer = HeapAlloc( ProcessHeap, 0, RecBufferLength );
292  if( !RecBuffer )
293  {
294  _tprintf( _T("ERROR: Out of memory\n") );
295  goto cleanup;
296  }
297 
298  /* Insert the ID field. */
299  ((PSHORT)&Buffer[i])[0] = htons( RequestID );
300  i += 2;
301 
302  /* Bits 0-7 of the second 16 are all 0, except for when recursion is
303  desired. */
304  Buffer[i] = 0x00;
305  if( State.recurse) Buffer[i] |= 0x01;
306  i += 1;
307 
308  /* Bits 8-15 of the second 16 are 0 for a query. */
309  Buffer[i] = 0x00;
310  i += 1;
311 
312  /* Only 1 question. */
313  ((PSHORT)&Buffer[i])[0] = htons( 1 );
314  i += 2;
315 
316  /* We aren't sending a response, so 0 out the rest of the header. */
317  Buffer[i] = 0x00;
318  Buffer[i + 1] = 0x00;
319  Buffer[i + 2] = 0x00;
320  Buffer[i + 3] = 0x00;
321  Buffer[i + 4] = 0x00;
322  Buffer[i + 5] = 0x00;
323  i += 6;
324 
325  /* Walk through the query address. Split each section delimited by '.'.
326  Format of the QNAME section is length|data, etc. Last one is null */
327  j = i;
328  i += 1;
329 
330  for( k = 0; k < strlen( pResolve ); k += 1 )
331  {
332  if( pResolve[k] != '.' )
333  {
334  Buffer[i] = pResolve[k];
335  i += 1;
336  }
337  else
338  {
339  Buffer[j] = (i - j) - 1;
340  j = i;
341  i += 1;
342  }
343  }
344 
345  Buffer[j] = (i - j) - 1;
346  Buffer[i] = 0x00;
347  i += 1;
348 
349  /* QTYPE */
350  ((PSHORT)&Buffer[i])[0] = htons( Type );
351  i += 2;
352 
353  /* QCLASS */
354  ((PSHORT)&Buffer[i])[0] = htons( ClassNametoClassID( State.Class ) );
355 
356  /* Ship off the request to the DNS server. */
357  bOk = SendRequest( Buffer,
358  BufferLength,
359  RecBuffer,
360  &RecBufferLength );
361  if( !bOk ) goto cleanup;
362 
363  /* Start parsing the received packet. */
364  Header2 = RecBuffer[3];
365  NumQuestions = ntohs( ((PSHORT)&RecBuffer[4])[0] );
366  NumAnswers = ntohs( ((PSHORT)&RecBuffer[6])[0] );
367  NumAuthority = ntohs( ((PUSHORT)&RecBuffer[8])[0] );
368  Type = 0;
369 
370  /* Check the RCODE for failure. */
371  d = Header2 & 0x0F;
372  if( d != RCODE_NOERROR )
373  {
374  switch( d )
375  {
376  case RCODE_NXDOMAIN:
377  _tprintf( _T("*** %s can't find %s: Non-existant domain\n"), State.DefaultServer, pAddr );
378  break;
379 
380  case RCODE_REFUSED:
381  _tprintf( _T("*** %s can't find %s: Query refused\n"), State.DefaultServer, pAddr );
382  break;
383 
384  default:
385  _tprintf( _T("*** %s can't find %s: Unknown RCODE\n"), State.DefaultServer, pAddr );
386  }
387 
388  goto cleanup;
389  }
390 
391  k = 12;
392 
393  if( NumQuestions )
394  {
395  /* Blow through the questions section since we don't care about it. */
396  for( i = 0; i < NumQuestions; i += 1 )
397  {
398  k += ExtractName( RecBuffer, pResult, k, 0 );
399  k += 4;
400  }
401  }
402 
403  if( NumAnswers )
404  {
405  /* Skip the name. */
406  k += ExtractName( RecBuffer, pResult, k, 0 );
407 
408  Type = ntohs( ((PUSHORT)&RecBuffer[k])[0] );
409  k += 8;
410 
411  d = ntohs( ((PUSHORT)&RecBuffer[k])[0] );
412  k += 2;
413 
414  if( TYPE_PTR == Type )
415  {
416  k += ExtractName( RecBuffer, pResult, k, d );
417  }
418  else if( TYPE_A == Type )
419  {
420  k += ExtractIP( RecBuffer, pResult, k );
421  }
422  }
423 
424  /* FIXME: This'll need to support more than PTR and A at some point. */
425  if( !strcmp( State.type, TypePTR ) )
426  {
427  if( TYPE_PTR == Type )
428  {
429  _tprintf( _T("%s name = %s\n"), pResolve, pResult );
430  }
431  else
432  {
433  }
434  }
435  else if( !strcmp( State.type, TypeA )
436  || !strcmp( State.type, TypeAAAA )
437  || !strcmp( State.type, TypeBoth ) )
438  {
439  if( (TYPE_A == Type) /*|| (TYPE_AAAA == Type)*/ )
440  {
441  if( 0 == NumAuthority )
442  _tprintf( _T("Non-authoritative answer:\n") );
443 
444  _tprintf( _T("Name: %s\n"), pAddr );
445  _tprintf( _T("Address: %s\n\n"), pResult );
446  }
447  else
448  {
449  _tprintf( _T("Name: %s\n"), pResult );
450  _tprintf( _T("Address: %s\n\n"), pAddr );
451  }
452  }
453 
454 cleanup:
455  /* Free memory. */
456  if( Buffer ) HeapFree( ProcessHeap, 0, Buffer );
457  if( RecBuffer ) HeapFree( ProcessHeap, 0, RecBuffer );
458 
459  RequestID += 1;
460 }
461 
463 {
464  int i;
465  BOOL NoMoreOptions = FALSE;
467  CHAR AddrToResolve[256];
468  CHAR Server[256];
469 
470  RtlZeroMemory( AddrToResolve, 256 );
471  RtlZeroMemory( Server, 256 );
472 
473  if( 2 == argc )
474  {
475  /* In the Windows nslookup, usage is only displayed if /? is the only
476  option specified on the command line. */
477  if( !strncmp( "/?", argv[1], 2 ) )
478  {
479  PrintUsage();
480  return 0;
481  }
482  }
483 
484  if( argc > 1 )
485  {
486  for( i = 1; i < argc; i += 1 )
487  {
488  if( NoMoreOptions )
489  {
490  strncpy( Server, argv[i], 255 );
491 
492  /* Determine which one to resolve. This is based on whether the
493  DNS server provided was an IP or an FQDN. */
494  if( IsValidIP( Server ) )
495  {
496  strncpy( State.DefaultServerAddress, Server, 16 );
497 
498  PerformInternalLookup( State.DefaultServerAddress,
499  State.DefaultServer );
500  }
501  else
502  {
503  strncpy( State.DefaultServer, Server, 255 );
504 
505  PerformInternalLookup( State.DefaultServer,
506  State.DefaultServerAddress );
507  }
508 
509  if( Interactive ) return 1;
510 
511  PerformLookup( AddrToResolve );
512 
513  return 0;
514  }
515  else
516  {
517  if( !strncmp( "-all", argv[i], 4 ) )
518  {
519  PrintState();
520  }
521  else if( !strncmp( "-type=", argv[i], 6 ) )
522  {
523  if( !strncmp( TypeA, &argv[i][6], strlen( TypeA ) ) )
524  {
525  State.type = TypeA;
526  }
527  else if( !strncmp( TypeAAAA, &argv[i][6], strlen( TypeAAAA ) ) )
528  {
529  State.type = TypeAAAA;
530  }
531  else if( !strncmp( TypeBoth, &argv[i][6], strlen( TypeBoth ) ) )
532  {
533  State.type = TypeBoth;
534  }
535  else if( !strncmp( TypeAny, &argv[i][6], strlen( TypeAny ) ) )
536  {
537  State.type = TypeAny;
538  }
539  else if( !strncmp( TypeCNAME, &argv[i][6], strlen( TypeCNAME ) ) )
540  {
541  State.type = TypeCNAME;
542  }
543  else if( !strncmp( TypeMX, &argv[i][6], strlen( TypeMX ) ) )
544  {
545  State.type = TypeMX;
546  }
547  else if( !strncmp( TypeNS, &argv[i][6], strlen( TypeNS ) ) )
548  {
549  State.type = TypeNS;
550  }
551  else if( !strncmp( TypePTR, &argv[i][6], strlen( TypePTR ) ) )
552  {
553  State.type = TypePTR;
554  }
555  else if( !strncmp( TypeSOA, &argv[i][6], strlen( TypeSOA ) ) )
556  {
557  State.type = TypeSOA;
558  }
559  else if( !strncmp( TypeSRV, &argv[i][6], strlen( TypeSRV ) ) )
560  {
561  State.type = TypeSRV;
562  }
563  else
564  {
565  _tprintf( _T("unknown query type: %s"), &argv[i][6] );
566  }
567  }
568  else if( !strncmp( "-domain=", argv[i], 8 ) )
569  {
570  strcpy( State.domain, &argv[i][8] );
571  }
572  else if( !strncmp( "-srchlist=", argv[i], 10 ) )
573  {
574  }
575  else if( !strncmp( "-root=", argv[i], 6 ) )
576  {
577  strcpy( State.root, &argv[i][6] );
578  }
579  else if( !strncmp( "-retry=", argv[i], 7 ) )
580  {
581  }
582  else if( !strncmp( "-timeout=", argv[i], 9 ) )
583  {
584  }
585  else if( !strncmp( "-querytype=", argv[i], 11 ) )
586  {
587  if( !strncmp( TypeA, &argv[i][11], strlen( TypeA ) ) )
588  {
589  State.type = TypeA;
590  }
591  else if( !strncmp( TypeAAAA, &argv[i][11], strlen( TypeAAAA ) ) )
592  {
593  State.type = TypeAAAA;
594  }
595  else if( !strncmp( TypeBoth, &argv[i][11], strlen( TypeBoth ) ) )
596  {
597  State.type = TypeBoth;
598  }
599  else if( !strncmp( TypeAny, &argv[i][11], strlen( TypeAny ) ) )
600  {
601  State.type = TypeAny;
602  }
603  else if( !strncmp( TypeCNAME, &argv[i][11], strlen( TypeCNAME ) ) )
604  {
605  State.type = TypeCNAME;
606  }
607  else if( !strncmp( TypeMX, &argv[i][11], strlen( TypeMX ) ) )
608  {
609  State.type = TypeMX;
610  }
611  else if( !strncmp( TypeNS, &argv[i][11], strlen( TypeNS ) ) )
612  {
613  State.type = TypeNS;
614  }
615  else if( !strncmp( TypePTR, &argv[i][11], strlen( TypePTR ) ) )
616  {
617  State.type = TypePTR;
618  }
619  else if( !strncmp( TypeSOA, &argv[i][11], strlen( TypeSOA ) ) )
620  {
621  State.type = TypeSOA;
622  }
623  else if( !strncmp( TypeSRV, &argv[i][11], strlen( TypeSRV ) ) )
624  {
625  State.type = TypeSRV;
626  }
627  else
628  {
629  _tprintf( _T("unknown query type: %s"), &argv[i][6] );
630  }
631  }
632  else if( !strncmp( "-class=", argv[i], 7 ) )
633  {
634  if( !strncmp( ClassIN, &argv[i][7], strlen( ClassIN ) ) )
635  {
636  State.Class = ClassIN;
637  }
638  else if( !strncmp( ClassAny, &argv[i][7], strlen( ClassAny ) ) )
639  {
640  State.Class = ClassAny;
641  }
642  else
643  {
644  _tprintf( _T("unknown query class: %s"), &argv[i][7] );
645  }
646  }
647  else if( !strncmp( "-ixfrver=", argv[i], 9 ) )
648  {
649  }
650  else if( !strncmp( "-debug", argv[i], 6 ) )
651  {
652  State.debug = TRUE;
653  }
654  else if( !strncmp( "-nodebug", argv[i], 8 ) )
655  {
656  State.debug = FALSE;
657  State.d2 = FALSE;
658  }
659  else if( !strncmp( "-d2", argv[i], 3 ) )
660  {
661  State.d2 = TRUE;
662  State.debug = TRUE;
663  }
664  else if( !strncmp( "-nod2", argv[i], 5 ) )
665  {
666  if( State.debug ) _tprintf( _T("d2 mode disabled; still in debug mode\n") );
667 
668  State.d2 = FALSE;
669  }
670  else if( !strncmp( "-defname", argv[i], 8 ) )
671  {
672  State.defname = TRUE;
673  }
674  else if( !strncmp( "-noddefname", argv[i], 10 ) )
675  {
676  State.defname = FALSE;
677  }
678  else if( !strncmp( "-recurse", argv[i], 8 ) )
679  {
680  State.recurse = TRUE;
681  }
682  else if( !strncmp( "-norecurse", argv[i], 10 ) )
683  {
684  State.recurse = FALSE;
685  }
686  else if( !strncmp( "-search", argv[i], 7 ) )
687  {
688  State.search = TRUE;
689  }
690  else if( !strncmp( "-nosearch", argv[i], 9 ) )
691  {
692  State.search = FALSE;
693  }
694  else if( !strncmp( "-vc", argv[i], 3 ) )
695  {
696  State.vc = TRUE;
697  }
698  else if( !strncmp( "-novc", argv[i], 5 ) )
699  {
700  State.vc = FALSE;
701  }
702  else if( !strncmp( "-msxfr", argv[i], 6 ) )
703  {
704  State.MSxfr = TRUE;
705  }
706  else if( !strncmp( "-nomsxfr", argv[i], 8 ) )
707  {
708  State.MSxfr = FALSE;
709  }
710  else if( !strncmp( "-", argv[i], 1 ) && (strlen( argv[i] ) == 1) )
711  {
712  /* Since we received just the plain - switch, we are going
713  to be entering interactive mode. We also will not be
714  parsing any more options. */
715  NoMoreOptions = TRUE;
716  Interactive = TRUE;
717  }
718  else
719  {
720  /* Grab the address to resolve. No more options accepted
721  past this point. */
722  strncpy( AddrToResolve, argv[i], 255 );
723  NoMoreOptions = TRUE;
724  }
725  }
726  }
727 
728  if( NoMoreOptions && !Interactive )
729  {
730  /* Get the FQDN of the DNS server. */
731  PerformInternalLookup( State.DefaultServerAddress,
732  State.DefaultServer );
733 
734  PerformLookup( AddrToResolve );
735 
736  return 0;
737  }
738  }
739 
740  /* Get the FQDN of the DNS server. */
741  PerformInternalLookup( State.DefaultServerAddress,
742  State.DefaultServer );
743 
744  return 1;
745 }
746 
748 {
749  _tprintf( _T("Default Server: %s\n"), State.DefaultServer );
750  _tprintf( _T("Address: %s\n\n"), State.DefaultServerAddress );
751 
752  /* TODO: Implement interactive mode. */
753 
754  _tprintf( _T("ERROR: Feature not implemented.\n") );
755 }
756 
757 int main( int argc, char* argv[] )
758 {
759  int i;
760  ULONG Status;
761  PFIXED_INFO pNetInfo = NULL;
762  ULONG NetBufLen = 0;
763  WSADATA wsaData;
764 
765  ProcessHeap = GetProcessHeap();
766  RequestID = 1;
767 
768  /* Set up the initial state. */
769  State.debug = FALSE;
770  State.defname = TRUE;
771  State.search = TRUE;
772  State.recurse = TRUE;
773  State.d2 = FALSE;
774  State.vc = FALSE;
775  State.ignoretc = FALSE;
776  State.port = 53;
777  State.type = TypeBoth;
778  State.Class = ClassIN;
779  State.timeout = 2;
780  State.retry = 1;
781  State.MSxfr = TRUE;
782  State.ixfrver = 1;
783 
784  RtlZeroMemory( State.root, 256 );
785  RtlZeroMemory( State.domain, 256 );
786  for( i = 0; i < 6; i += 1 ) RtlZeroMemory( State.srchlist[i], 256 );
787  RtlZeroMemory( State.DefaultServer, 256 );
788  RtlZeroMemory( State.DefaultServerAddress, 16 );
789 
790  memcpy( State.root, DEFAULT_ROOT, sizeof(DEFAULT_ROOT) );
791 
792  /* We don't know how long of a buffer it will want to return. So we'll
793  pass an empty one now and let it fail only once, instead of guessing. */
794  Status = GetNetworkParams( pNetInfo, &NetBufLen );
795  if( Status == ERROR_BUFFER_OVERFLOW )
796  {
797  pNetInfo = (PFIXED_INFO)HeapAlloc( ProcessHeap, 0, NetBufLen );
798  if( pNetInfo == NULL )
799  {
800  _tprintf( _T("ERROR: Out of memory\n") );
801 
802  return -1;
803  }
804 
805  /* For real this time. */
806  Status = GetNetworkParams( pNetInfo, &NetBufLen );
807  if( Status != NO_ERROR )
808  {
809  _tprintf( _T("Error in GetNetworkParams call\n") );
810 
811  HeapFree( ProcessHeap, 0, pNetInfo );
812 
813  return -2;
814  }
815  }
816 
817  strncpy( State.domain, pNetInfo->DomainName, 255 );
818  strncpy( State.srchlist[0], pNetInfo->DomainName, 255 );
819  strncpy( State.DefaultServerAddress,
820  pNetInfo->DnsServerList.IpAddress.String,
821  15 );
822 
823  HeapFree( ProcessHeap, 0, pNetInfo );
824 
825  WSAStartup( MAKEWORD(2,2), &wsaData );
826 
827  switch( ParseCommandLine( argc, argv ) )
828  {
829  case 0:
830  /* This means that it was a /? parameter. */
831  break;
832 
833  default:
834  /* Anything else means we enter interactive mode. The only exception
835  to this is when the host to resolve was provided on the command
836  line. */
837  InteractiveMode();
838  }
839 
840  WSACleanup();
841  return 0;
842 }
signed char * PCHAR
Definition: retypes.h:7
static int argc
Definition: ServiceArgs.c:12
#define _tprintf
Definition: tchar.h:506
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
void ReverseIP(PCHAR pIP, PCHAR pReturn)
Definition: utility.c:249
#define TRUE
Definition: types.h:120
void InteractiveMode()
Definition: nslookup.c:747
Definition: userinit.h:56
Type
Definition: Type.h:6
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
void PrintUsage()
Definition: nslookup.c:68
signed short * PSHORT
Definition: retypes.h:6
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define MAKEWORD(a, b)
Definition: typedefs.h:247
#define ERROR_BUFFER_OVERFLOW
Definition: winerror.h:185
int main(int argc, char *argv[])
Definition: nslookup.c:757
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
char CHAR
Definition: xmlstorage.h:175
IP_ADDRESS_STRING IpAddress
Definition: iptypes.h:47
INT WSAAPI WSACleanup(VOID)
Definition: startup.c:60
#define TypeA
Definition: nslookup.h:13
char String[4 *4]
Definition: iptypes.h:42
#define TypeCNAME
Definition: nslookup.h:17
static void Server(int port)
Definition: srltest.c:69
#define NO_ERROR
Definition: dderror.h:5
#define DEFAULT_ROOT
Definition: nslookup.h:63
#define ntohs(x)
Definition: module.h:208
static char ** argv
Definition: ServiceArgs.c:11
#define ARPA_SIG
Definition: nslookup.h:64
BOOL PerformInternalLookup(PCHAR pAddr, PCHAR pResult)
Definition: nslookup.c:79
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define TypePTR
Definition: nslookup.h:20
_In_ ULONG BufferLength
Definition: usbdlib.h:225
void PerformLookup(PCHAR pAddr)
Definition: nslookup.c:236
DWORD WINAPI GetNetworkParams(PFIXED_INFO pFixedInfo, PULONG pOutBufLen)
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
#define RCODE_NXDOMAIN
Definition: nslookup.h:51
smooth NULL
Definition: ftsmooth.c:416
char DomainName[MAX_DOMAIN_NAME_LEN+4]
Definition: iptypes.h:82
Definition: bufpool.h:45
#define RCODE_NOERROR
Definition: nslookup.h:48
#define ClassAny
Definition: nslookup.h:34
#define _T(x)
Definition: vfdio.h:22
unsigned int BOOL
Definition: ntddk_ex.h:94
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
USHORT TypeNametoTypeID(PCHAR TypeName)
Definition: utility.c:819
#define d
Definition: ke_i.h:81
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
int ExtractName(PCHAR pBuffer, PCHAR pOutput, USHORT Offset, UCHAR Limit)
Definition: utility.c:343
#define ClassIN
Definition: nslookup.h:33
void PrintState()
Definition: nslookup.c:18
#define TypeNS
Definition: nslookup.h:19
unsigned char UCHAR
Definition: xmlstorage.h:181
STATE State
Definition: nslookup.c:14
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define TypeSRV
Definition: nslookup.h:22
struct FIXED_INFO * PFIXED_INFO
USHORT ClassNametoClassID(PCHAR ClassName)
Definition: utility.c:848
Status
Definition: gdiplustypes.h:24
#define TypeBoth
Definition: nslookup.h:15
#define TypeAny
Definition: nslookup.h:16
unsigned short USHORT
Definition: pedump.c:61
int ExtractIP(PCHAR pBuffer, PCHAR pOutput, USHORT Offset)
Definition: utility.c:397
#define TypeMX
Definition: nslookup.h:18
BOOL IsValidIP(PCHAR pInput)
Definition: utility.c:306
#define RCODE_REFUSED
Definition: nslookup.h:53
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
char * cleanup(char *str)
Definition: wpickclick.c:99
ULONG RequestID
Definition: nslookup.c:16
#define htons(x)
Definition: module.h:213
BOOL SendRequest(PCHAR pInBuffer, ULONG InBufferLength, PCHAR pOutBuffer, PULONG pOutBufferLength)
Definition: utility.c:11
IP_ADDR_STRING DnsServerList
Definition: iptypes.h:84
#define TYPE_A
Definition: ftp_var.h:36
int k
Definition: mpi.c:3369
#define HeapFree(x, y, z)
Definition: compat.h:394
unsigned short * PUSHORT
Definition: retypes.h:2
#define CLASS_IN
Definition: nslookup.h:36
HANDLE ProcessHeap
Definition: nslookup.c:15
#define TypeAAAA
Definition: nslookup.h:14
#define TypeSOA
Definition: nslookup.h:21
BOOL ParseCommandLine(int argc, char *argv[])
Definition: nslookup.c:462