Please revert this, it is implemented ass-half-backwards and does not use the correct DNSAPI services provided by Windows.
Best regards, Alex Ionescu
On Fri, Oct 23, 2009 at 7:25 PM, lsuggs@svn.reactos.org wrote:
Author: lsuggs Date: Fri Oct 23 19:25:05 2009 New Revision: 43700
URL: http://svn.reactos.org/svn/reactos?rev=43700&view=rev Log: First push of nslookup implementation.
Added: trunk/reactos/base/applications/network/nslookup/ (with props) trunk/reactos/base/applications/network/nslookup/nslookup.c (with props) trunk/reactos/base/applications/network/nslookup/nslookup.h (with props) trunk/reactos/base/applications/network/nslookup/nslookup.rbuild (with props) trunk/reactos/base/applications/network/nslookup/nslookup.rc (with props) trunk/reactos/base/applications/network/nslookup/utility.c (with props) Modified: trunk/reactos/base/applications/network/network.rbuild trunk/reactos/boot/bootdata/packages/reactos.dff
Modified: trunk/reactos/base/applications/network/network.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/network/n... ============================================================================== --- trunk/reactos/base/applications/network/network.rbuild [iso-8859-1] (original) +++ trunk/reactos/base/applications/network/network.rbuild [iso-8859-1] Fri Oct 23 19:25:05 2009 @@ -22,6 +22,9 @@ <directory name="netstat"> <xi:include href="netstat/netstat.rbuild" /> </directory>
- <directory name="nslookup">
- <xi:include href="nslookup/nslookup.rbuild" />
- </directory>
<directory name="ping"> <xi:include href="ping/ping.rbuild" /> </directory>
Propchange: trunk/reactos/base/applications/network/nslookup/
--- bugtraq:logregex (added) +++ bugtraq:logregex Fri Oct 23 19:25:05 2009 @@ -1,0 +1,2 @@ +([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))? +(\d+)
Propchange: trunk/reactos/base/applications/network/nslookup/
bugtraq:message = See issue #%BUGID% for more details.
Propchange: trunk/reactos/base/applications/network/nslookup/
bugtraq:url = http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%
Propchange: trunk/reactos/base/applications/network/nslookup/
tsvn:logminsize = 10
Added: trunk/reactos/base/applications/network/nslookup/nslookup.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/network/n... ============================================================================== --- trunk/reactos/base/applications/network/nslookup/nslookup.c (added) +++ trunk/reactos/base/applications/network/nslookup/nslookup.c [iso-8859-1] Fri Oct 23 19:25:05 2009 @@ -1,0 +1,858 @@ +/*
- PROJECT: ReactOS nslookup utility
- LICENSE: GPL - See COPYING in the top level directory
- FILE: applications/network/nslookup/nslookup.c
- PURPOSE: Perform DNS lookups
- COPYRIGHT: Copyright 2009 Lucas Suggs lucas.suggs@gmail.com
- */
+#include <windows.h> +#include <windns.h> +#include <winsock2.h> +#include <tchar.h> +#include <stdio.h> +#include <stdlib.h> +#include <iphlpapi.h> +#include "nslookup.h"
+STATE State; +HANDLE ProcessHeap; +ULONG RequestID;
+void PrintState() +{
- _tprintf( _T("Default Server: (null)\n\n") );
- _tprintf( _T("Set options:\n") );
- _tprintf( _T(" ") );
- if( !State.debug ) _tprintf( _T("no") );
- _tprintf( _T("debug\n") );
- _tprintf( _T(" ") );
- if( !State.defname ) _tprintf( _T("no") );
- _tprintf( _T("defname\n") );
- _tprintf( _T(" ") );
- if( !State.search ) _tprintf( _T("no") );
- _tprintf( _T("search\n") );
- _tprintf( _T(" ") );
- if( !State.recurse ) _tprintf( _T("no") );
- _tprintf( _T("recurse\n") );
- _tprintf( _T(" ") );
- if( !State.d2 ) _tprintf( _T("no") );
- _tprintf( _T("d2\n") );
- _tprintf( _T(" ") );
- if( !State.vc ) _tprintf( _T("no") );
- _tprintf( _T("vc\n") );
- _tprintf( _T(" ") );
- if( !State.ignoretc ) _tprintf( _T("no") );
- _tprintf( _T("ignoretc\n") );
- _tprintf( _T(" port=%d\n"), State.port );
- _tprintf( _T(" type=%s\n"), State.type );
- _tprintf( _T(" class=%s\n"), State.Class );
- _tprintf( _T(" timeout=%d\n"), (int)State.timeout );
- _tprintf( _T(" retry=%d\n"), (int)State.retry );
- _tprintf( _T(" root=%s\n"), State.root );
- _tprintf( _T(" domain=%s\n"), State.domain );
- _tprintf( _T(" ") );
- if( !State.MSxfr ) _tprintf( _T("no") );
- _tprintf( _T("MSxfr\n") );
- _tprintf( _T(" IXFRversion=%d\n"), (int)State.ixfrver );
- _tprintf( _T(" srchlist=%s\n\n"), State.srchlist[0] );
+}
+void PrintUsage() +{
- _tprintf( _T("Usage:\n"
- " nslookup [-opt ...] # interactive mode using"
- " default server\n nslookup [-opt ...] - server #"
- " interactive mode using 'server'\n nslookup [-opt ...]"
- " host # just look up 'host' using default server\n"
- " nslookup [-opt ...] host server # just look up 'host'"
- " using 'server'\n") );
+}
+BOOL PerformInternalLookup( PCHAR pAddr, PCHAR pResult ) +{
- /* Needed to issue DNS packets and parse them. */
- PCHAR Buffer = NULL, RecBuffer = NULL;
- CHAR pResolve[256];
- ULONG BufferLength = 0, RecBufferLength = 512;
- int i = 0, j = 0, k = 0, d = 0;
- BOOL bOk = FALSE;
- /* Makes things easier when parsing the response packet. */
- UCHAR Header1, Header2;
- USHORT NumQuestions;
- USHORT NumAnswers;
- USHORT NumAuthority;
- USHORT NumAdditional;
- USHORT Type;
- if( (strlen( pAddr ) + 1) > 255 ) return FALSE;
- Type = TYPE_A;
- if( IsValidIP( pAddr ) ) Type = TYPE_PTR;
- /* If it's a PTR lookup then append the ARPA sig to the end. */
- if( Type == TYPE_PTR )
- {
- ReverseIP( pAddr, pResolve );
- strcat( pResolve, ARPA_SIG );
- }
- else
- {
- strcpy( pResolve, pAddr );
- }
- /* Base header length + length of QNAME + length of QTYPE and QCLASS */
- BufferLength = 12 + (strlen( pResolve ) + 2) + 4;
- /* Allocate memory for the buffer. */
- Buffer = HeapAlloc( ProcessHeap, 0, BufferLength );
- if( !Buffer )
- {
- _tprintf( _T("ERROR: Out of memory\n") );
- goto cleanup;
- }
- /* Allocate the receiving buffer. */
- RecBuffer = HeapAlloc( ProcessHeap, 0, RecBufferLength );
- if( !RecBuffer )
- {
- _tprintf( _T("ERROR: Out of memory\n") );
- goto cleanup;
- }
- /* Insert the ID field. */
- ((PSHORT)&Buffer[i])[0] = htons( RequestID );
- i += 2;
- /* Bits 0-7 of the second 16 are all 0, except for when recursion is
- desired. */
- Buffer[i] = 0x00;
- if( State.recurse) Buffer[i] |= 0x01;
- i += 1;
- /* Bits 8-15 of the second 16 are 0 for a query. */
- Buffer[i] = 0x00;
- i += 1;
- /* Only 1 question. */
- ((PSHORT)&Buffer[i])[0] = htons( 1 );
- i += 2;
- /* We aren't sending a response, so 0 out the rest of the header. */
- Buffer[i] = 0x00;
- Buffer[i + 1] = 0x00;
- Buffer[i + 2] = 0x00;
- Buffer[i + 3] = 0x00;
- Buffer[i + 4] = 0x00;
- Buffer[i + 5] = 0x00;
- i += 6;
- /* Walk through the query address. Split each section delimited by '.'.
- Format of the QNAME section is length|data, etc. Last one is null */
- j = i;
- i += 1;
- for( k = 0; k < strlen( pResolve ); k += 1 )
- {
- if( pResolve[k] != '.' )
- {
- Buffer[i] = pResolve[k];
- i += 1;
- }
- else
- {
- Buffer[j] = (i - j) - 1;
- j = i;
- i += 1;
- }
- }
- Buffer[j] = (i - j) - 1;
- Buffer[i] = 0x00;
- i += 1;
- /* QTYPE */
- ((PSHORT)&Buffer[i])[0] = htons( Type );
- i += 2;
- /* QCLASS */
- ((PSHORT)&Buffer[i])[0] = htons( CLASS_IN );
- /* Ship the request off to the DNS server. */
- bOk = SendRequest( Buffer,
- BufferLength,
- RecBuffer,
- &RecBufferLength );
- if( !bOk ) goto cleanup;
- /* Start parsing the received packet. */
- Header1 = RecBuffer[2];
- Header2 = RecBuffer[3];
- NumQuestions = ntohs( ((PSHORT)&RecBuffer[4])[0] );
- NumAnswers = ntohs( ((PSHORT)&RecBuffer[6])[0] );
- NumAuthority = ntohs( ((PUSHORT)&RecBuffer[8])[0] );
- NumAdditional = ntohs( ((PUSHORT)&RecBuffer[10])[0] );
- k = 12;
- /* We don't care about the questions section, blow through it. */
- if( NumQuestions )
- {
- for( i = 0; i < NumQuestions; i += 1 )
- {
- /* Quick way to skip the domain name section. */
- k += ExtractName( RecBuffer, pResult, k, 0 );
- k += 4;
- }
- }
- /* Skip the answer name. */
- k += ExtractName( RecBuffer, pResult, k, 0 );
- Type = ntohs( ((PUSHORT)&RecBuffer[k])[0] );
- k += 8;
- d = ntohs( ((PUSHORT)&RecBuffer[k])[0] );
- k += 2;
- if( TYPE_PTR == Type )
- {
- k += ExtractName( RecBuffer, pResult, k, d );
- }
- else if( TYPE_A == Type )
- {
- k += ExtractIP( RecBuffer, pResult, k );
- }
+cleanup:
- /* Free memory. */
- if( Buffer ) HeapFree( ProcessHeap, 0, Buffer );
- if( RecBuffer ) HeapFree( ProcessHeap, 0, RecBuffer );
- RequestID += 1;
- return bOk;
+}
+void PerformLookup( PCHAR pAddr ) +{
- /* Needed to issue DNS packets and parse them. */
- PCHAR Buffer = NULL, RecBuffer = NULL;
- CHAR pResolve[256];
- CHAR pResult[256];
- ULONG BufferLength = 0, RecBufferLength = 512;
- int i = 0, j = 0, k = 0, d = 0;
- BOOL bOk = FALSE;
- /* Makes things easier when parsing the response packet. */
- UCHAR Header1, Header2;
- USHORT NumQuestions;
- USHORT NumAnswers;
- USHORT NumAuthority;
- USHORT NumAdditional;
- USHORT Type;
- if( (strlen( pAddr ) + 1) > 255 ) return;
- _tprintf( _T("Server: %s\n"), State.DefaultServer );
- _tprintf( _T("Address: %s\n\n"), State.DefaultServerAddress );
- if( !strcmp( TypeA, State.type )
- || !strcmp( TypeAAAA, State.type )
- || !strcmp( TypeBoth, State.type ) )
- {
- Type = TYPE_A;
- if( IsValidIP( pAddr ) ) Type = TYPE_PTR;
- }
- else
- Type = TypeNametoTypeID( State.type );
- /* If it's a PTR lookup then append the ARPA sig to the end. */
- if( (Type == TYPE_PTR) && IsValidIP( pAddr ) )
- {
- ReverseIP( pAddr, pResolve );
- strcat( pResolve, ARPA_SIG );
- }
- else
- {
- strcpy( pResolve, pAddr );
- }
- /* Base header length + length of QNAME + length of QTYPE and QCLASS */
- BufferLength = 12 + (strlen( pResolve ) + 2) + 4;
- /* Allocate memory for the buffer. */
- Buffer = HeapAlloc( ProcessHeap, 0, BufferLength );
- if( !Buffer )
- {
- _tprintf( _T("ERROR: Out of memory\n") );
- goto cleanup;
- }
- /* Allocate memory for the return buffer. */
- RecBuffer = HeapAlloc( ProcessHeap, 0, RecBufferLength );
- if( !RecBuffer )
- {
- _tprintf( _T("ERROR: Out of memory\n") );
- goto cleanup;
- }
- /* Insert the ID field. */
- ((PSHORT)&Buffer[i])[0] = htons( RequestID );
- i += 2;
- /* Bits 0-7 of the second 16 are all 0, except for when recursion is
- desired. */
- Buffer[i] = 0x00;
- if( State.recurse) Buffer[i] |= 0x01;
- i += 1;
- /* Bits 8-15 of the second 16 are 0 for a query. */
- Buffer[i] = 0x00;
- i += 1;
- /* Only 1 question. */
- ((PSHORT)&Buffer[i])[0] = htons( 1 );
- i += 2;
- /* We aren't sending a response, so 0 out the rest of the header. */
- Buffer[i] = 0x00;
- Buffer[i + 1] = 0x00;
- Buffer[i + 2] = 0x00;
- Buffer[i + 3] = 0x00;
- Buffer[i + 4] = 0x00;
- Buffer[i + 5] = 0x00;
- i += 6;
- /* Walk through the query address. Split each section delimited by '.'.
- Format of the QNAME section is length|data, etc. Last one is null */
- j = i;
- i += 1;
- for( k = 0; k < strlen( pResolve ); k += 1 )
- {
- if( pResolve[k] != '.' )
- {
- Buffer[i] = pResolve[k];
- i += 1;
- }
- else
- {
- Buffer[j] = (i - j) - 1;
- j = i;
- i += 1;
- }
- }
- Buffer[j] = (i - j) - 1;
- Buffer[i] = 0x00;
- i += 1;
- /* QTYPE */
- ((PSHORT)&Buffer[i])[0] = htons( Type );
- i += 2;
- /* QCLASS */
- ((PSHORT)&Buffer[i])[0] = htons( ClassNametoClassID( State.Class ) );
- /* Ship off the request to the DNS server. */
- bOk = SendRequest( Buffer,
- BufferLength,
- RecBuffer,
- &RecBufferLength );
- if( !bOk ) goto cleanup;
- /* Start parsing the received packet. */
- Header1 = RecBuffer[2];
- Header2 = RecBuffer[3];
- NumQuestions = ntohs( ((PSHORT)&RecBuffer[4])[0] );
- NumAnswers = ntohs( ((PSHORT)&RecBuffer[6])[0] );
- NumAuthority = ntohs( ((PUSHORT)&RecBuffer[8])[0] );
- NumAdditional = ntohs( ((PUSHORT)&RecBuffer[10])[0] );
- Type = 0;
- /* Check the RCODE for failure. */
- d = Header2 & 0x0F;
- if( d != RCODE_NOERROR )
- {
- switch( d )
- {
- case RCODE_NXDOMAIN:
- _tprintf( _T("*** %s can't find %s: Non-existant domain\n"), State.DefaultServer, pAddr );
- break;
- case RCODE_REFUSED:
- _tprintf( _T("*** %s can't find %s: Query refused\n"), State.DefaultServer, pAddr );
- break;
- default:
- _tprintf( _T("*** %s can't find %s: Unknown RCODE\n"), State.DefaultServer, pAddr );
- }
- goto cleanup;
- }
- k = 12;
- if( NumQuestions )
- {
- /* Blow through the questions section since we don't care about it. */
- for( i = 0; i < NumQuestions; i += 1 )
- {
- k += ExtractName( RecBuffer, pResult, k, 0 );
- k += 4;
- }
- }
- if( NumAnswers )
- {
- /* Skip the name. */
- k += ExtractName( RecBuffer, pResult, k, 0 );
- Type = ntohs( ((PUSHORT)&RecBuffer[k])[0] );
- k += 8;
- d = ntohs( ((PUSHORT)&RecBuffer[k])[0] );
- k += 2;
- if( TYPE_PTR == Type )
- {
- k += ExtractName( RecBuffer, pResult, k, d );
- }
- else if( TYPE_A == Type )
- {
- k += ExtractIP( RecBuffer, pResult, k );
- }
- }
- /* FIXME: This'll need to support more than PTR and A at some point. */
- if( !strcmp( State.type, TypePTR ) )
- {
- if( TYPE_PTR == Type )
- {
- _tprintf( _T("%s name = %s\n"), pResolve, pResult );
- }
- else
- {
- }
- }
- else if( !strcmp( State.type, TypeA )
- || !strcmp( State.type, TypeAAAA )
- || !strcmp( State.type, TypeBoth ) )
- {
- if( (TYPE_A == Type) /*|| (TYPE_AAAA == Type)*/ )
- {
- if( 0 == NumAuthority )
- _tprintf( _T("Non-authoritative answer:\n") );
- _tprintf( _T("Name: %s\n"), pAddr );
- _tprintf( _T("Address: %s\n\n"), pResult );
- }
- else
- {
- _tprintf( _T("Name: %s\n"), pResult );
- _tprintf( _T("Address: %s\n\n"), pAddr );
- }
- }
+cleanup:
- /* Free memory. */
- if( Buffer ) HeapFree( ProcessHeap, 0, Buffer );
- if( RecBuffer ) HeapFree( ProcessHeap, 0, RecBuffer );
- RequestID += 1;
+}
+BOOL ParseCommandLine( int argc, char* argv[] ) +{
- int i;
- BOOL NoMoreOptions = FALSE;
- BOOL Interactive = FALSE;
- CHAR AddrToResolve[256];
- CHAR Server[256];
- RtlZeroMemory( AddrToResolve, 256 );
- RtlZeroMemory( Server, 256 );
- if( 2 == argc )
- {
- /* In the Windows nslookup, usage is only displayed if /? is the only
- option specified on the command line. */
- if( !strncmp( "/?", argv[1], 2 ) )
- {
- PrintUsage();
- return 0;
- }
- }
- if( argc > 1 )
- {
- for( i = 1; i < argc; i += 1 )
- {
- if( NoMoreOptions )
- {
- strncpy( Server, argv[i], 255 );
- /* Determine which one to resolve. This is based on whether the
- DNS server provided was an IP or an FQDN. */
- if( IsValidIP( Server ) )
- {
- strncpy( State.DefaultServerAddress, Server, 16 );
- PerformInternalLookup( State.DefaultServerAddress,
- State.DefaultServer );
- }
- else
- {
- strncpy( State.DefaultServer, Server, 255 );
- PerformInternalLookup( State.DefaultServer,
- State.DefaultServerAddress );
- }
- if( Interactive ) return 1;
- PerformLookup( AddrToResolve );
- return 0;
- }
- else
- {
- if( !strncmp( "-all", argv[i], 4 ) )
- {
- PrintState();
- }
- else if( !strncmp( "-type=", argv[i], 6 ) )
- {
- if( !strncmp( TypeA, &argv[i][6], strlen( TypeA ) ) )
- {
- State.type = TypeA;
- }
- else if( !strncmp( TypeAAAA, &argv[i][6], strlen( TypeAAAA ) ) )
- {
- State.type = TypeAAAA;
- }
- else if( !strncmp( TypeBoth, &argv[i][6], strlen( TypeBoth ) ) )
- {
- State.type = TypeBoth;
- }
- else if( !strncmp( TypeAny, &argv[i][6], strlen( TypeAny ) ) )
- {
- State.type = TypeAny;
- }
- else if( !strncmp( TypeCNAME, &argv[i][6], strlen( TypeCNAME ) ) )
- {
- State.type = TypeCNAME;
- }
- else if( !strncmp( TypeMX, &argv[i][6], strlen( TypeMX ) ) )
- {
- State.type = TypeMX;
- }
- else if( !strncmp( TypeNS, &argv[i][6], strlen( TypeNS ) ) )
- {
- State.type = TypeNS;
- }
- else if( !strncmp( TypePTR, &argv[i][6], strlen( TypePTR ) ) )
- {
- State.type = TypePTR;
- }
- else if( !strncmp( TypeSOA, &argv[i][6], strlen( TypeSOA ) ) )
- {
- State.type = TypeSOA;
- }
- else if( !strncmp( TypeSRV, &argv[i][6], strlen( TypeSRV ) ) )
- {
- State.type = TypeSRV;
- }
- else
- {
- _tprintf( _T("unknown query type: %s"), &argv[i][6] );
- }
- }
- else if( !strncmp( "-domain=", argv[i], 8 ) )
- {
- strcpy( State.domain, &argv[i][8] );
- }
- else if( !strncmp( "-srchlist=", argv[i], 10 ) )
- {
- }
- else if( !strncmp( "-root=", argv[i], 6 ) )
- {
- strcpy( State.root, &argv[i][6] );
- }
- else if( !strncmp( "-retry=", argv[i], 7 ) )
- {
- }
- else if( !strncmp( "-timeout=", argv[i], 9 ) )
- {
- }
- else if( !strncmp( "-querytype=", argv[i], 11 ) )
- {
- if( !strncmp( TypeA, &argv[i][11], strlen( TypeA ) ) )
- {
- State.type = TypeA;
- }
- else if( !strncmp( TypeAAAA, &argv[i][11], strlen( TypeAAAA ) ) )
- {
- State.type = TypeAAAA;
- }
- else if( !strncmp( TypeBoth, &argv[i][11], strlen( TypeBoth ) ) )
- {
- State.type = TypeBoth;
- }
- else if( !strncmp( TypeAny, &argv[i][11], strlen( TypeAny ) ) )
- {
- State.type = TypeAny;
- }
- else if( !strncmp( TypeCNAME, &argv[i][11], strlen( TypeCNAME ) ) )
- {
- State.type = TypeCNAME;
- }
- else if( !strncmp( TypeMX, &argv[i][11], strlen( TypeMX ) ) )
- {
- State.type = TypeMX;
- }
- else if( !strncmp( TypeNS, &argv[i][11], strlen( TypeNS ) ) )
- {
- State.type = TypeNS;
- }
- else if( !strncmp( TypePTR, &argv[i][11], strlen( TypePTR ) ) )
- {
- State.type = TypePTR;
- }
- else if( !strncmp( TypeSOA, &argv[i][11], strlen( TypeSOA ) ) )
- {
- State.type = TypeSOA;
- }
- else if( !strncmp( TypeSRV, &argv[i][11], strlen( TypeSRV ) ) )
- {
- State.type = TypeSRV;
- }
- else
- {
- _tprintf( _T("unknown query type: %s"), &argv[i][6] );
- }
- }
- else if( !strncmp( "-class=", argv[i], 7 ) )
- {
- if( !strncmp( ClassIN, &argv[i][7], strlen( ClassIN ) ) )
- {
- State.Class = ClassIN;
- }
- else if( !strncmp( ClassAny, &argv[i][7], strlen( ClassAny ) ) )
- {
- State.Class = ClassAny;
- }
- else
- {
- _tprintf( _T("unknown query class: %s"), &argv[i][7] );
- }
- }
- else if( !strncmp( "-ixfrver=", argv[i], 9 ) )
- {
- }
- else if( !strncmp( "-debug", argv[i], 6 ) )
- {
- State.debug = TRUE;
- }
- else if( !strncmp( "-nodebug", argv[i], 8 ) )
- {
- State.debug = FALSE;
- State.d2 = FALSE;
- }
- else if( !strncmp( "-d2", argv[i], 3 ) )
- {
- State.d2 = TRUE;
- State.debug = TRUE;
- }
- else if( !strncmp( "-nod2", argv[i], 5 ) )
- {
- if( State.debug ) _tprintf( _T("d2 mode disabled; still in debug mode\n") );
- State.d2 = FALSE;
- }
- else if( !strncmp( "-defname", argv[i], 8 ) )
- {
- State.defname = TRUE;
- }
- else if( !strncmp( "-noddefname", argv[i], 10 ) )
- {
- State.defname = FALSE;
- }
- else if( !strncmp( "-recurse", argv[i], 8 ) )
- {
- State.recurse = TRUE;
- }
- else if( !strncmp( "-norecurse", argv[i], 10 ) )
- {
- State.recurse = FALSE;
- }
- else if( !strncmp( "-search", argv[i], 7 ) )
- {
- State.search = TRUE;
- }
- else if( !strncmp( "-nosearch", argv[i], 9 ) )
- {
- State.search = FALSE;
- }
- else if( !strncmp( "-vc", argv[i], 3 ) )
- {
- State.vc = TRUE;
- }
- else if( !strncmp( "-novc", argv[i], 5 ) )
- {
- State.vc = FALSE;
- }
- else if( !strncmp( "-msxfr", argv[i], 6 ) )
- {
- State.MSxfr = TRUE;
- }
- else if( !strncmp( "-nomsxfr", argv[i], 8 ) )
- {
- State.MSxfr = FALSE;
- }
- else if( !strncmp( "-", argv[i], 1 ) && (strlen( argv[i] ) == 1) )
- {
- /* Since we received just the plain - switch, we are going
- to be entering interactive mode. We also will not be
- parsing any more options. */
- NoMoreOptions = TRUE;
- Interactive = TRUE;
- }
- else
- {
- /* Grab the address to resolve. No more options accepted
- past this point. */
- strncpy( AddrToResolve, argv[i], 255 );
- NoMoreOptions = TRUE;
- }
- }
- }
- if( NoMoreOptions && !Interactive )
- {
- /* Get the FQDN of the DNS server. */
- PerformInternalLookup( State.DefaultServerAddress,
- State.DefaultServer );
- PerformLookup( AddrToResolve );
- return 0;
- }
- }
- /* Get the FQDN of the DNS server. */
- PerformInternalLookup( State.DefaultServerAddress,
- State.DefaultServer );
- return 1;
+}
+void InteractiveMode() +{
- _tprintf( _T("Default Server: %s\n"), State.DefaultServer );
- _tprintf( _T("Address: %s\n\n"), State.DefaultServerAddress );
- /* TODO: Implement interactive mode. */
- _tprintf( _T("ERROR: Feature not implemented.\n") );
+}
+int main( int argc, char* argv[] ) +{
- int i;
- ULONG Status;
- PFIXED_INFO pNetInfo = NULL;
- ULONG NetBufLen = 0;
- WSADATA wsaData;
- ProcessHeap = GetProcessHeap();
- RequestID = 1;
- /* Set up the initial state. */
- State.debug = FALSE;
- State.defname = TRUE;
- State.search = TRUE;
- State.recurse = TRUE;
- State.d2 = FALSE;
- State.vc = FALSE;
- State.ignoretc = FALSE;
- State.port = 53;
- State.type = TypeBoth;
- State.Class = ClassIN;
- State.timeout = 2;
- State.retry = 1;
- State.MSxfr = TRUE;
- State.ixfrver = 1;
- RtlZeroMemory( State.root, 256 );
- RtlZeroMemory( State.domain, 256 );
- for( i = 0; i < 6; i += 1 ) RtlZeroMemory( State.srchlist[i], 256 );
- RtlZeroMemory( State.DefaultServer, 256 );
- RtlZeroMemory( State.DefaultServerAddress, 16 );
- strncpy( State.root, DEFAULT_ROOT, strlen( DEFAULT_ROOT ) );
- /* We don't know how long of a buffer it will want to return. So we'll
- pass an empty one now and let it fail only once, instead of guessing. */
- Status = GetNetworkParams( pNetInfo, &NetBufLen );
- if( Status == ERROR_BUFFER_OVERFLOW )
- {
- pNetInfo = (PFIXED_INFO)HeapAlloc( ProcessHeap, 0, NetBufLen );
- if( pNetInfo == NULL )
- {
- _tprintf( _T("ERROR: Out of memory\n") );
- return -1;
- }
- /* For real this time. */
- Status = GetNetworkParams( pNetInfo, &NetBufLen );
- if( Status != NO_ERROR )
- {
- _tprintf( _T("Error in GetNetworkParams call\n") );
- HeapFree( ProcessHeap, 0, pNetInfo );
- return -2;
- }
- }
- strncpy( State.domain, pNetInfo->DomainName, 255 );
- strncpy( State.srchlist[0], pNetInfo->DomainName, 255 );
- strncpy( State.DefaultServerAddress,
- pNetInfo->DnsServerList.IpAddress.String,
- 15 );
- HeapFree( ProcessHeap, 0, pNetInfo );
- WSAStartup( MAKEWORD(2,2), &wsaData );
- switch( ParseCommandLine( argc, argv ) )
- {
- case 0:
- /* This means that it was a /? parameter. */
- break;
- default:
- /* Anything else means we enter interactive mode. The only exception
- to this is when the host to resolve was provided on the command
- line. */
- InteractiveMode();
- }
- WSACleanup();
- return 0;
+}
Propchange: trunk/reactos/base/applications/network/nslookup/nslookup.c
svn:eol-style = native
Added: trunk/reactos/base/applications/network/nslookup/nslookup.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/network/n... ============================================================================== --- trunk/reactos/base/applications/network/nslookup/nslookup.h (added) +++ trunk/reactos/base/applications/network/nslookup/nslookup.h [iso-8859-1] Fri Oct 23 19:25:05 2009 @@ -1,0 +1,104 @@ +#define TypeA "A" +#define TypeAAAA "AAAA" +#define TypeBoth "A+AAAA" +#define TypeAny "ANY" +#define TypeCNAME "CNAME" +#define TypeMX "MX" +#define TypeNS "NS" +#define TypePTR "PTR" +#define TypeSOA "SOA" +#define TypeSRV "SRV"
+#define TYPE_A 0x01 +#define TYPE_NS 0x02 +#define TYPE_CNAME 0x05 +#define TYPE_SOA 0x06 +#define TYPE_WKS 0x0B +#define TYPE_PTR 0x0C +#define TYPE_MX 0x0F +#define TYPE_ANY 0xFF
+#define ClassIN "IN" +#define ClassAny "ANY"
+#define CLASS_IN 0x01 +#define CLASS_ANY 0xFF
+#define OPCODE_QUERY 0x00 +#define OPCODE_IQUERY 0x01 +#define OPCODE_STATUS 0x02
+#define OpcodeQuery "QUERY" +#define OpcodeIQuery "IQUERY" +#define OpcodeStatus "STATUS" +#define OpcodeReserved "RESERVED"
+#define RCODE_NOERROR 0x00 +#define RCODE_FORMERR 0x01 +#define RCODE_FAILURE 0x02 +#define RCODE_NXDOMAIN 0x03 +#define RCODE_NOTIMP 0x04 +#define RCODE_REFUSED 0x05
+#define RCodeNOERROR "NOERROR" +#define RCodeFORMERR "FORMERR" +#define RCodeFAILURE "FAILURE" +#define RCodeNXDOMAIN "NXDOMAIN" +#define RCodeNOTIMP "NOTIMP" +#define RCodeREFUSED "REFUSED" +#define RCodeReserved "RESERVED"
+#define DEFAULT_ROOT "A.ROOT-SERVERS.NET." +#define ARPA_SIG ".in-addr.arpa"
+typedef struct _STATE +{
- BOOL debug;
- BOOL defname;
- BOOL d2;
- BOOL recurse;
- BOOL search;
- BOOL vc;
- BOOL ignoretc;
- BOOL MSxfr;
- CHAR domain[256];
- CHAR srchlist[6][256];
- CHAR root[256];
- DWORD retry;
- DWORD timeout;
- DWORD ixfrver;
- PCHAR type;
- PCHAR Class;
- USHORT port;
- CHAR DefaultServer[256];
- CHAR DefaultServerAddress[16];
+} STATE, *PSTATE;
+/* nslookup.c */
+extern STATE State; +extern HANDLE ProcessHeap;
+/* utility.c */
+BOOL SendRequest( PCHAR pInBuffer,
- ULONG InBufferLength,
- PCHAR pOutBuffer,
- PULONG pOutBufferLength );
+int ExtractName( PCHAR pBuffer,
- PCHAR pOutput,
- USHORT Offset,
- UCHAR Limit );
+void ReverseIP( PCHAR pIP, PCHAR pReturn ); +BOOL IsValidIP( PCHAR pInput ); +int ExtractIP( PCHAR pBuffer, PCHAR pOutput, USHORT Offset ); +void PrintD2( PCHAR pBuffer, DWORD BufferLength ); +void PrintDebug( PCHAR pBuffer, DWORD BufferLength ); +PCHAR OpcodeIDtoOpcodeName( UCHAR Opcode ); +PCHAR RCodeIDtoRCodeName( UCHAR RCode ); +PCHAR TypeIDtoTypeName( USHORT TypeID ); +USHORT TypeNametoTypeID( PCHAR TypeName ); +PCHAR ClassIDtoClassName( USHORT ClassID ); +USHORT ClassNametoClassID( PCHAR ClassName );
Propchange: trunk/reactos/base/applications/network/nslookup/nslookup.h
svn:eol-style = native
Added: trunk/reactos/base/applications/network/nslookup/nslookup.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/network/n... ============================================================================== --- trunk/reactos/base/applications/network/nslookup/nslookup.rbuild (added) +++ trunk/reactos/base/applications/network/nslookup/nslookup.rbuild [iso-8859-1] Fri Oct 23 19:25:05 2009 @@ -1,0 +1,13 @@ +<?xml version="1.0"?> +<!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd"> +<module name="nslookup" type="win32cui" installbase="system32" installname="nslookup.exe">
- <include base="nslookup">.</include>
- <library>kernel32</library>
- <library>user32</library>
- <library>ws2_32</library>
- <library>snmpapi</library>
- <library>iphlpapi</library>
- <file>nslookup.c</file>
- <file>utility.c</file>
- <file>nslookup.rc</file>
+</module>
Propchange: trunk/reactos/base/applications/network/nslookup/nslookup.rbuild
svn:eol-style = native
Added: trunk/reactos/base/applications/network/nslookup/nslookup.rc URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/network/n... ============================================================================== --- trunk/reactos/base/applications/network/nslookup/nslookup.rc (added) +++ trunk/reactos/base/applications/network/nslookup/nslookup.rc [iso-8859-1] Fri Oct 23 19:25:05 2009 @@ -1,0 +1,5 @@ +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS TCP/IPv4 Win32 nslookup\0" +#define REACTOS_STR_INTERNAL_NAME "nslookup\0" +#define REACTOS_STR_ORIGINAL_FILENAME "nslookup.exe\0" +#define REACTOS_STR_ORIGINAL_COPYRIGHT "Lucas Suggs (lucas.suggs@gmail.com)\0" +#include <reactos/version.rc>
Propchange: trunk/reactos/base/applications/network/nslookup/nslookup.rc
svn:eol-style = native
Added: trunk/reactos/base/applications/network/nslookup/utility.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/network/n... ============================================================================== --- trunk/reactos/base/applications/network/nslookup/utility.c (added) +++ trunk/reactos/base/applications/network/nslookup/utility.c [iso-8859-1] Fri Oct 23 19:25:05 2009 @@ -1,0 +1,852 @@ +/*
- PROJECT: ReactOS nslookup utility
- LICENSE: GPL - See COPYING in the top level directory
- FILE: applications/network/nslookup/utility.c
- PURPOSE: Support functions for nslookup.c
- COPYRIGHT: Copyright 2009 Lucas Suggs lucas.suggs@gmail.com
- */
+#include <windows.h> +#include <tchar.h> +#include <stdio.h> +#include "nslookup.h"
+BOOL SendRequest( PCHAR pInBuffer,
- ULONG InBufferLength,
- PCHAR pOutBuffer,
- PULONG pOutBufferLength )
+{
- int j;
- USHORT RequestID, ResponseID;
- BOOL bWait;
- SOCKET s;
- SOCKADDR_IN RecAddr, RecAddr2, SendAddr;
- int SendAddrLen = sizeof(SendAddr);
- RtlZeroMemory( &RecAddr, sizeof(SOCKADDR_IN) );
- RtlZeroMemory( &RecAddr2, sizeof(SOCKADDR_IN) );
- RtlZeroMemory( &SendAddr, sizeof(SOCKADDR_IN) );
- /* Pull the request ID from the buffer. */
- RequestID = ntohs( ((PSHORT)&pInBuffer[0])[0] );
- /* If D2 flags is enabled, then display D2 information. */
- if( State.d2 ) PrintD2( pInBuffer, InBufferLength );
- /* Create the sockets for both send and receive. */
- s = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
- /* Set up the structure to tell it where we are going. */
- RecAddr.sin_family = AF_INET;
- RecAddr.sin_port = htons( State.port );
- RecAddr.sin_addr.s_addr = inet_addr( State.DefaultServerAddress );
- /* Set up the structure to tell it what port to listen on. */
- RecAddr2.sin_family = AF_INET;
- RecAddr2.sin_port = htons( State.port );
- RecAddr2.sin_addr.s_addr = htonl( INADDR_ANY );
- /* Bind the receive socket. */
- bind( s, (SOCKADDR*)&RecAddr2, sizeof(RecAddr2) );
- /* Send the datagram to the DNS server. */
- j = sendto( s,
- pInBuffer,
- InBufferLength,
- 0,
- (SOCKADDR*)&RecAddr,
- sizeof(RecAddr) );
- if( j == SOCKET_ERROR )
- {
- switch( WSAGetLastError() )
- {
- case WSANOTINITIALISED:
- _tprintf( _T("sendto() failed with WSANOTINITIALIZED\n") );
- break;
- case WSAENETDOWN:
- _tprintf( _T("sendto() failed with WSAENETDOWN\n") );
- break;
- case WSAEACCES:
- _tprintf( _T("sendto() failed with WSAEACCES\n") );
- break;
- case WSAEINVAL:
- _tprintf( _T("sendto() failed with WSAEINVAL\n") );
- break;
- case WSAEINTR:
- _tprintf( _T("sendto() failed with WSAEINTR\n") );
- break;
- case WSAEINPROGRESS:
- _tprintf( _T("sendto() failed with WSAEINPROGRESS\n") );
- break;
- case WSAEFAULT:
- _tprintf( _T("sendto() failed with WSAEFAULT\n") );
- break;
- case WSAENETRESET:
- _tprintf( _T("sendto() failed with WSAENETRESET\n") );
- break;
- case WSAENOBUFS:
- _tprintf( _T("sendto() failed with WSAENOBUFS\n") );
- break;
- case WSAENOTCONN:
- _tprintf( _T("sendto() failed with WSAENOTCONN\n") );
- break;
- case WSAENOTSOCK:
- _tprintf( _T("sendto() failed with WSAENOTSOCK\n") );
- break;
- case WSAEOPNOTSUPP:
- _tprintf( _T("sendto() failed with WSAEOPNOTSUPP\n") );
- break;
- case WSAESHUTDOWN:
- _tprintf( _T("sendto() failed with WSAESHUTDOWN\n") );
- break;
- case WSAEWOULDBLOCK:
- _tprintf( _T("sendto() failed with WSAEWOULDBLOCK\n") );
- break;
- case WSAEMSGSIZE:
- _tprintf( _T("sendto() failed with WSAEMSGSIZE\n") );
- break;
- case WSAEHOSTUNREACH:
- _tprintf( _T("sendto() failed with WSAEHOSTUNREACH\n") );
- break;
- case WSAECONNABORTED:
- _tprintf( _T("sendto() failed with WSAECONNABORTED\n") );
- break;
- case WSAECONNRESET:
- _tprintf( _T("sendto() failed with WSAECONNRESET\n") );
- break;
- case WSAEADDRNOTAVAIL:
- _tprintf( _T("sendto() failed with WSAEADDRNOTAVAIL\n") );
- break;
- case WSAEAFNOSUPPORT:
- _tprintf( _T("sendto() failed with WSAEAFNOSUPPORT\n") );
- break;
- case WSAEDESTADDRREQ:
- _tprintf( _T("sendto() failed with WSAEDESTADDRREQ\n") );
- break;
- case WSAENETUNREACH:
- _tprintf( _T("sendto() failed with WSAENETUNREACH\n") );
- break;
- case WSAETIMEDOUT:
- _tprintf( _T("sendto() failed with WSAETIMEDOUT\n") );
- break;
- default:
- _tprintf( _T("sendto() failed with unknown error\n") );
- }
- return FALSE;
- }
- bWait = TRUE;
- while( bWait )
- {
- /* Wait for the DNS reply. */
- j = recvfrom( s,
- pOutBuffer,
- *pOutBufferLength,
- 0,
- (SOCKADDR*)&SendAddr,
- &SendAddrLen );
- if( j == SOCKET_ERROR )
- {
- switch( WSAGetLastError() )
- {
- case WSANOTINITIALISED:
- _tprintf( _T("recvfrom() failed with WSANOTINITIALIZED\n") );
- break;
- case WSAENETDOWN:
- _tprintf( _T("recvfrom() failed with WSAENETDOWN\n") );
- break;
- case WSAEACCES:
- _tprintf( _T("recvfrom() failed with WSAEACCES\n") );
- break;
- case WSAEINVAL:
- _tprintf( _T("recvfrom() failed with WSAEINVAL\n") );
- break;
- case WSAEINTR:
- _tprintf( _T("recvfrom() failed with WSAEINTR\n") );
- break;
- case WSAEINPROGRESS:
- _tprintf( _T("recvfrom() failed with WSAEINPROGRESS\n") );
- break;
- case WSAEFAULT:
- _tprintf( _T("recvfrom() failed with WSAEFAULT\n") );
- break;
- case WSAENETRESET:
- _tprintf( _T("recvfrom() failed with WSAENETRESET\n") );
- break;
- case WSAENOBUFS:
- _tprintf( _T("recvfrom() failed with WSAENOBUFS\n") );
- break;
- case WSAENOTCONN:
- _tprintf( _T("recvfrom() failed with WSAENOTCONN\n") );
- break;
- case WSAENOTSOCK:
- _tprintf( _T("recvfrom() failed with WSAENOTSOCK\n") );
- break;
- case WSAEOPNOTSUPP:
- _tprintf( _T("recvfrom() failed with WSAEOPNOTSUPP\n") );
- break;
- case WSAESHUTDOWN:
- _tprintf( _T("recvfrom() failed with WSAESHUTDOWN\n") );
- break;
- case WSAEWOULDBLOCK:
- _tprintf( _T("recvfrom() failed with WSAEWOULDBLOCK\n") );
- break;
- case WSAEMSGSIZE:
- _tprintf( _T("recvfrom() failed with WSAEMSGSIZE\n") );
- break;
- case WSAEHOSTUNREACH:
- _tprintf( _T("recvfrom() failed with WSAEHOSTUNREACH\n") );
- break;
- case WSAECONNABORTED:
- _tprintf( _T("recvfrom() failed with WSAECONNABORTED\n") );
- break;
- case WSAECONNRESET:
- _tprintf( _T("recvfrom() failed with WSAECONNRESET\n") );
- break;
- case WSAEADDRNOTAVAIL:
- _tprintf( _T("recvfrom() failed with WSAEADDRNOTAVAIL\n") );
- break;
- case WSAEAFNOSUPPORT:
- _tprintf( _T("recvfrom() failed with WSAEAFNOSUPPORT\n") );
- break;
- case WSAEDESTADDRREQ:
- _tprintf( _T("recvfrom() failed with WSAEDESTADDRREQ\n") );
- break;
- case WSAENETUNREACH:
- _tprintf( _T("recvfrom() failed with WSAENETUNREACH\n") );
- break;
- case WSAETIMEDOUT:
- _tprintf( _T("recvfrom() failed with WSAETIMEDOUT\n") );
- break;
- default:
- _tprintf( _T("recvfrom() failed with unknown error\n") );
- }
- return FALSE;
- }
- ResponseID = ntohs( ((PSHORT)&pOutBuffer[0])[0] );
- if( ResponseID == RequestID ) bWait = FALSE;
- }
- /* We don't need the sockets anymore. */
- closesocket( s );
- /* If debug information then display debug information. */
- if( State.debug ) PrintDebug( pOutBuffer, j );
- /* Return the real output buffer length. */
- *pOutBufferLength = j;
- return TRUE;
+}
+void ReverseIP( PCHAR pIP, PCHAR pReturn ) +{
- int i;
- int j;
- int k = 0;
- j = strlen( pIP ) - 1;
- i = j;
- /* We have A.B.C.D
- We will turn this into D.C.B.A and stick it in pReturn */
- /* A */
- for( ; i > 0; i -= 1 ) if( '.' == pIP[i] ) break;
- strncpy( &pReturn[k], &pIP[i + 1], (j - i) );
- k += (j - i);
- pReturn[k] = '.';
- k += 1;
- i -= 1;
- j = i;
- /* B */
- for( ; i > 0; i -= 1 ) if( '.' == pIP[i] ) break;
- strncpy( &pReturn[k], &pIP[i + 1], (j - i) );
- k += (j - i);
- pReturn[k] = '.';
- k += 1;
- i -= 1;
- j = i;
- /* C */
- for( ; i > 0; i -= 1 ) if( '.' == pIP[i] ) break;
- strncpy( &pReturn[k], &pIP[i + 1], (j - i) );
- k += (j - i);
- pReturn[k] = '.';
- k += 1;
- i -= 1;
- j = i;
- /* D */
- for( ; i > 0; i -= 1 );
- strncpy( &pReturn[k], &pIP[i], (j - i) + 1 );
- k += (j - i) + 1;
- pReturn[k] = '\0';
+}
+BOOL IsValidIP( PCHAR pInput ) +{
- int i = 0, l = 0, b = 0, c = 1;
- /* Max length of an IP, e.g. 255.255.255.255, is 15 characters. */
- l = strlen( pInput );
- if( l > 15 ) return FALSE;
- /* 'b' is the count of the current segment. It gets reset after seeing a
- '.'. */
- for( ; i < l; i += 1 )
- {
- if( '.' == pInput[i] )
- {
- if( !b ) return FALSE;
- if( b > 3 ) return FALSE;
- b = 0;
- c += 1;
- }
- else
- {
- b += 1;
- if( (pInput[i] < '0') || (pInput[i] > '9') ) return FALSE;
- }
- }
- if( b > 3 ) return FALSE;
- /* 'c' is the number of segments seen. If it's less than 4, then it's not
- a valid IP. */
- if( c < 4 ) return FALSE;
- return TRUE;
+}
+int ExtractName( PCHAR pBuffer, PCHAR pOutput, USHORT Offset, UCHAR Limit ) +{
- int c = 0, d = 0, i = 0, j = 0, k = 0, l = 0, m = 0;
- i = Offset;
- /* If Limit == 0, then we assume "no" limit. */
- d = Limit;
- if( 0 == Limit ) d = 255;
- while( d > 0 )
- {
- l = pBuffer[i] & 0xFF;
- i += 1;
- if( !m ) c += 1;
- if( 0xC0 == l )
- {
- if( !m ) c += 1;
- m = 1;
- d += (255 - Limit);
- i = pBuffer[i];
- }
- else
- {
- for( j = 0; j < l; j += 1 )
- {
- pOutput[k] = pBuffer[i];
- i += 1;
- if( !m ) c += 1;
- k += 1;
- d -= 1;
- }
- d -= 1;
- if( !pBuffer[i] || (d < 1) ) break;
- pOutput[k] = '.';
- k += 1;
- }
- };
- if( !m )
- {
- if( !Limit ) c += 1;
- }
- pOutput[k] = '\0';
- return c;
+}
+int ExtractIP( PCHAR pBuffer, PCHAR pOutput, USHORT Offset ) +{
- int c = 0, l = 0, i = 0, v = 0;
- i = Offset;
- v = (UCHAR)pBuffer[i];
- l += 1;
- i += 1;
- sprintf( &pOutput[c], "%d.", v );
- c += strlen( &pOutput[c] );
- v = (UCHAR)pBuffer[i];
- l += 1;
- i += 1;
- sprintf( &pOutput[c], "%d.", v );
- c += strlen( &pOutput[c] );
- v = (UCHAR)pBuffer[i];
- l += 1;
- i += 1;
- sprintf( &pOutput[c], "%d.", v );
- c += strlen( &pOutput[c] );
- v = (UCHAR)pBuffer[i];
- l += 1;
- i += 1;
- sprintf( &pOutput[c], "%d", v );
- c += strlen( &pOutput[c] );
- pOutput[c] = '\0';
- return l;
+}
+void PrintD2( PCHAR pBuffer, DWORD BufferLength ) +{
- USHORT RequestID;
- UCHAR Header1, Header2;
- USHORT NumQuestions, NumAnswers, NumAuthority, NumAdditional;
- USHORT Type, Class;
- CHAR pName[255];
- int i = 0, k = 0;
- RequestID = ntohs( ((PUSHORT)&pBuffer[i])[0] );
- i += 2;
- Header1 = pBuffer[i];
- i += 1;
- Header2 = pBuffer[i];
- i += 1;
- NumQuestions = ntohs( ((PSHORT)&pBuffer[i])[0] );
- i += 2;
- NumAnswers = ntohs( ((PSHORT)&pBuffer[i])[0] );
- i += 2;
- NumAuthority = ntohs( ((PUSHORT)&pBuffer[i])[0] );
- i += 2;
- NumAdditional = ntohs( ((PUSHORT)&pBuffer[i])[0] );
- i += 2;
- _tprintf( _T("------------\n") );
- _tprintf( _T("SendRequest(), len %d\n"), (int)BufferLength );
- _tprintf( _T(" HEADER:\n") );
- _tprintf( _T(" opcode = %s, id = %d, rcode = %s\n"),
- OpcodeIDtoOpcodeName( (Header1 & 0x78) >> 3 ),
- (int)RequestID,
- RCodeIDtoRCodeName( Header2 & 0x0F ) );
- _tprintf( _T(" header flags: query") );
- if( Header1 & 0x01 ) _tprintf( _T(", want recursion") );
- _tprintf( _T("\n") );
- _tprintf( _T(" questions = %d, answers = %d,"
- " authority records = %d, additional = %d\n\n"),
- (int)NumQuestions,
- (int)NumAnswers,
- (int)NumAuthority,
- (int)NumAdditional );
- if( NumQuestions )
- {
- _tprintf( _T(" QUESTIONS:\n") );
- for( k = 0; k < NumQuestions; k += 1 )
- {
- i += ExtractName( pBuffer, pName, i, 0 );
- _tprintf( _T(" %s"), pName );
- Type = ntohs( ((PUSHORT)&pBuffer[i])[0] );
- i += 2;
- Class = ntohs( ((PUSHORT)&pBuffer[i])[0] );
- i += 2;
- _tprintf( _T(", type = %s, class = %s\n"),
- TypeIDtoTypeName( Type ),
- ClassIDtoClassName( Class ) );
- }
- }
- _tprintf( _T("\n------------\n") );
+}
+void PrintDebug( PCHAR pBuffer, DWORD BufferLength ) +{
- USHORT ResponseID;
- UCHAR Header1, Header2;
- USHORT NumQuestions, NumAnswers, NumAuthority, NumAdditional;
- USHORT Type, Class;
- ULONG TTL;
- CHAR pName[255];
- int d = 0, i = 0, k = 0;
- ResponseID = ntohs( ((PUSHORT)&pBuffer[i])[0] );
- i += 2;
- Header1 = pBuffer[i];
- i += 1;
- Header2 = pBuffer[i];
- i += 1;
- NumQuestions = ntohs( ((PSHORT)&pBuffer[i])[0] );
- i += 2;
- NumAnswers = ntohs( ((PSHORT)&pBuffer[i])[0] );
- i += 2;
- NumAuthority = ntohs( ((PUSHORT)&pBuffer[i])[0] );
- i += 2;
- NumAdditional = ntohs( ((PUSHORT)&pBuffer[i])[0] );
- i += 2;
- _tprintf( _T("------------\n") );
- _tprintf( _T("Got answer (%d bytes):\n"), (int)BufferLength );
- _tprintf( _T(" HEADER:\n") );
- _tprintf( _T(" opcode = %s, id = %d, rcode = %s\n"),
- OpcodeIDtoOpcodeName( (Header1 & 0x78) >> 3 ),
- (int)ResponseID,
- RCodeIDtoRCodeName( Header2 & 0x0F ) );
- _tprintf( _T(" header flags: response") );
- if( Header1 & 0x01 ) _tprintf( _T(", want recursion") );
- if( Header2 & 0x80 ) _tprintf( _T(", recursion avail.") );
- _tprintf( _T("\n") );
- _tprintf( _T(" questions = %d, answers = %d, "
- "authority records = %d, additional = %d\n\n"),
- (int)NumQuestions,
- (int)NumAnswers,
- (int)NumAuthority,
- (int)NumAdditional );
- if( NumQuestions )
- {
- _tprintf( _T(" QUESTIONS:\n") );
- for( k = 0; k < NumQuestions; k += 1 )
- {
- i += ExtractName( pBuffer, pName, i, 0 );
- _tprintf( _T(" %s"), pName );
- Type = ntohs( ((PUSHORT)&pBuffer[i])[0] );
- i += 2;
- Class = ntohs( ((PUSHORT)&pBuffer[i])[0] );
- i += 2;
- _tprintf( _T(", type = %s, class = %s\n"),
- TypeIDtoTypeName( Type ),
- ClassIDtoClassName( Class ) );
- }
- }
- if( NumAnswers )
- {
- _tprintf( _T(" ANSWERS:\n") );
- for( k = 0; k < NumAnswers; k += 1 )
- {
- _tprintf( _T(" -> ") );
- /* Print out the name. */
- i += ExtractName( pBuffer, pName, i, 0 );
- _tprintf( _T("%s\n"), pName );
- /* Print out the type, class and data length. */
- Type = ntohs( ((PUSHORT)&pBuffer[i])[0] );
- i += 2;
- Class = ntohs( ((PUSHORT)&pBuffer[i])[0] );
- i += 2;
- TTL = ntohl( ((PULONG)&pBuffer[i])[0] );
- i += 4;
- d = ntohs( ((PUSHORT)&pBuffer[i])[0] );
- i += 2;
- _tprintf( _T(" type = %s, class = %s, dlen = %d\n"),
- TypeIDtoTypeName( Type ),
- ClassIDtoClassName( Class ),
- d );
- /* Print out the answer. */
- if( TYPE_A == Type )
- {
- i += ExtractIP( pBuffer, pName, i );
- _tprintf( _T(" internet address = %s\n"), pName );
- }
- else
- {
- i += ExtractName( pBuffer, pName, i, d );
- _tprintf( _T(" name = %s\n"), pName );
- }
- _tprintf( _T(" ttl = %d ()\n"), (int)TTL );
- }
- }
- if( NumAuthority )
- {
- _tprintf( _T(" AUTHORITY RECORDS:\n") );
- for( k = 0; k < NumAuthority; k += 1 )
- {
- /* Print out the zone name. */
- i += ExtractName( pBuffer, pName, i, 0 );
- _tprintf( _T(" -> %s\n"), pName );
- /* Print out the type, class, data length and TTL. */
- Type = ntohs( ((PUSHORT)&pBuffer[i])[0] );
- i += 2;
- Class = ntohs( ((PUSHORT)&pBuffer[i])[0] );
- i += 2;
- TTL = ntohl( ((PULONG)&pBuffer[i])[0] );
- i += 4;
- d = ntohs( ((PUSHORT)&pBuffer[i])[0] );
- i += 2;
- _tprintf( _T(" type = %s, class = %s, dlen = %d\n"),
- TypeIDtoTypeName( Type ),
- ClassIDtoClassName( Class ),
- d );
- /* TODO: There might be more types? */
- if( TYPE_NS == Type )
- {
- /* Print out the NS. */
- i += ExtractName( pBuffer, pName, i, d );
- _tprintf( _T(" nameserver = %s\n"), pName );
- _tprintf( _T(" ttl = %d ()\n"), (int)TTL );
- }
- else if( TYPE_SOA == Type )
- {
- _tprintf( _T(" ttl = %d ()\n"), (int)TTL );
- /* Print out the primary NS. */
- i += ExtractName( pBuffer, pName, i, 0 );
- _tprintf( _T(" primary name server = %s\n"), pName );
- /* Print out the responsible mailbox. */
- i += ExtractName( pBuffer, pName, i, 0 );
- _tprintf( _T(" responsible mail addr = %s\n"), pName );
- /* Print out the serial, refresh, retry, expire and default TTL. */
- _tprintf( _T(" serial = ()\n") );
- _tprintf( _T(" refresh = ()\n") );
- _tprintf( _T(" retry = ()\n") );
- _tprintf( _T(" expire = ()\n") );
- _tprintf( _T(" default TTL = ()\n") );
- i += 20;
- }
- }
- }
- if( NumAdditional )
- {
- _tprintf( _T(" ADDITIONAL:\n") );
- for( k = 0; k < NumAdditional; k += 1 )
- {
- /* Print the name. */
- i += ExtractName( pBuffer, pName, i, 0 );
- _tprintf( _T(" -> %s\n"), pName );
- /* Print out the type, class, data length and TTL. */
- Type = ntohs( ((PUSHORT)&pBuffer[i])[0] );
- i += 2;
- Class = ntohs( ((PUSHORT)&pBuffer[i])[0] );
- i += 2;
- TTL = ntohl( ((PULONG)&pBuffer[i])[0] );
- i += 4;
- d = ntohs( ((PUSHORT)&pBuffer[i])[0] );
- i += 2;
- _tprintf( _T(" type = %s, class = %s, dlen = %d\n"),
- TypeIDtoTypeName( Type ),
- ClassIDtoClassName( Class ),
- d );
- /* TODO: There might be more types? */
- if( TYPE_A == Type )
- {
- /* Print out the NS. */
- i += ExtractIP( pBuffer, pName, i );
- _tprintf( _T(" internet address = %s\n"), pName );
- _tprintf( _T(" ttl = %d ()\n"), (int)TTL );
- }
- }
- }
- _tprintf( _T("\n------------\n") );
+}
+PCHAR OpcodeIDtoOpcodeName( UCHAR Opcode ) +{
- switch( Opcode & 0x0F )
- {
- case OPCODE_QUERY:
- return OpcodeQuery;
- case OPCODE_IQUERY:
- return OpcodeIQuery;
- case OPCODE_STATUS:
- return OpcodeStatus;
- default:
- return OpcodeReserved;
- }
+}
+PCHAR RCodeIDtoRCodeName( UCHAR RCode ) +{
- switch( RCode & 0x0F )
- {
- case RCODE_NOERROR:
- return RCodeNOERROR;
- case RCODE_FORMERR:
- return RCodeFORMERR;
- case RCODE_FAILURE:
- return RCodeFAILURE;
- case RCODE_NXDOMAIN:
- return RCodeNXDOMAIN;
- case RCODE_NOTIMP:
- return RCodeNOTIMP;
- case RCODE_REFUSED:
- return RCodeREFUSED;
- default:
- return RCodeReserved;
- }
+}
+PCHAR TypeIDtoTypeName( USHORT TypeID ) +{
- switch( TypeID )
- {
- case TYPE_A:
- return TypeA;
- case TYPE_NS:
- return TypeNS;
- case TYPE_CNAME:
- return TypeCNAME;
- case TYPE_SOA:
- return TypeSOA;
- case TYPE_WKS:
- return TypeSRV;
- case TYPE_PTR:
- return TypePTR;
- case TYPE_MX:
- return TypeMX;
- case TYPE_ANY:
- return TypeAny;
- default:
- return "Unknown";
- }
+}
+USHORT TypeNametoTypeID( PCHAR TypeName ) +{
- if( !strncmp( TypeName, TypeA, strlen( TypeA ) ) ) return TYPE_A;
- if( !strncmp( TypeName, TypeNS, strlen( TypeNS ) ) ) return TYPE_NS;
- if( !strncmp( TypeName, TypeCNAME, strlen( TypeCNAME ) ) ) return TYPE_CNAME;
- if( !strncmp( TypeName, TypeSOA, strlen( TypeSOA ) ) ) return TYPE_SOA;
- if( !strncmp( TypeName, TypeSRV, strlen( TypeSRV ) ) ) return TYPE_WKS;
- if( !strncmp( TypeName, TypePTR, strlen( TypePTR ) ) ) return TYPE_PTR;
- if( !strncmp( TypeName, TypeMX, strlen( TypeMX ) ) ) return TYPE_MX;
- if( !strncmp( TypeName, TypeAny, strlen( TypeAny ) ) ) return TYPE_ANY;
- return 0;
+}
+PCHAR ClassIDtoClassName( USHORT ClassID ) +{
- switch( ClassID )
- {
- case CLASS_IN:
- return ClassIN;
- case CLASS_ANY:
- return ClassAny;
- default:
- return "Unknown";
- }
+}
+USHORT ClassNametoClassID( PCHAR ClassName ) +{
- if( !strncmp( ClassName, ClassIN, strlen( ClassIN ) ) ) return CLASS_IN;
- if( !strncmp( ClassName, ClassAny, strlen( ClassAny ) ) ) return CLASS_ANY;
- return 0;
+}
Propchange: trunk/reactos/base/applications/network/nslookup/utility.c
svn:eol-style = native
Modified: trunk/reactos/boot/bootdata/packages/reactos.dff URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/bootdata/packages/reac... ============================================================================== --- trunk/reactos/boot/bootdata/packages/reactos.dff [iso-8859-1] (original) +++ trunk/reactos/boot/bootdata/packages/reactos.dff [iso-8859-1] Fri Oct 23 19:25:05 2009 @@ -64,6 +64,7 @@ base\applications\network\ftp\ftp.exe 1 base\applications\network\ipconfig\ipconfig.exe 1 base\applications\network\netstat\netstat.exe 1 +base\applications\network\nslookup\nslookup.exe 1 base\applications\network\ping\ping.exe 1 base\applications\network\telnet\telnet.exe 1 base\applications\network\tracert\tracert.exe 1
Alex Ionescu wrote:
Please revert this, it is implemented ass-half-backwards and does not use the correct DNSAPI services provided by Windows.
nslookup doesn't use DNSAPI even on Windows (not for queries at least). What I'm more disappointed about is that we are rewriting a standard BSD tool, which has already been ported to Windows:
nslookup on Windows uses DNSAPI exclusively for DNS resolution, and the Rtl* network APIs for IP processing.
In fact, there are even lots of Wine postings about people trying to run nslookup and failing due to missing dnsapi functionality.
Best regards, Alex Ionescu
On Sat, Oct 24, 2009 at 4:04 AM, KJK::Hyperion hackbunny@reactos.org wrote:
Alex Ionescu wrote:
Please revert this, it is implemented ass-half-backwards and does not use the correct DNSAPI services provided by Windows.
nslookup doesn't use DNSAPI even on Windows (not for queries at least). What I'm more disappointed about is that we are rewriting a standard BSD tool, which has already been ported to Windows:
https://www.isc.org/software/bind
Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
Alex Ionescu wrote:
nslookup on Windows uses DNSAPI exclusively for DNS resolution, and the Rtl* network APIs for IP processing.
I'm just not seeing it. This is a query:
ChildEBP RetAddr 0013ee7c 00fbb3af WS2_32!send 0013f1e4 00fba369 nslookup!SendRequest+0x19b 0014f250 00fbae10 nslookup!MergeHostInfoPtr+0xc0 0015f48c 00fbb017 nslookup!GetHostDomainPrivate+0x13f 0015f4d8 00fbb192 nslookup!GetHostDomain+0x67 0015f54c 00fb54f3 nslookup!GetHostInfoByName+0x107 0015f5bc 00fb56a7 nslookup!DoLookup+0xcd 0015f7e0 00fb72ee nslookup!LookupHost+0x114 0015f804 00fb66ab nslookup!yylex+0x6e8 0015f878 00fbc6b9 nslookup!main+0x531 0015f8bc 758dd0e9 nslookup!_initterm_e+0x163 0015f8c8 772219bb kernel32!BaseThreadInitThunk+0xe 0015f908 7722198e ntdll!__RtlUserThreadStart+0x23 0015f920 00000000 ntdll!_RtlUserThreadStart+0x1b
(I especially like the "yylex" routine suggesting nslookup's main loop is a hand-made parser on top of a lex lexer)
The only two dnsapi.dll routines imported by nslookup.exe are DnsQueryConfigAllocEx and DnsFreeConfigStructure, which are only called at startup:
ChildEBP RetAddr 000dfb58 00fb6431 DNSAPI!DnsQueryConfigAllocEx 000dfbd8 00fbc6b9 nslookup!main+0x2b7 000dfc1c 758dd0e9 nslookup!_initterm_e+0x163 000dfc28 772219bb kernel32!BaseThreadInitThunk+0xe 000dfc68 7722198e ntdll!__RtlUserThreadStart+0x23 000dfc80 00000000 ntdll!_RtlUserThreadStart+0x1b
ChildEBP RetAddr 000dfb5c 00fb659b DNSAPI!DnsFreeConfigStructure 000dfbd8 00fbc6b9 nslookup!main+0x421 000dfc1c 758dd0e9 nslookup!_initterm_e+0x163 000dfc28 772219bb kernel32!BaseThreadInitThunk+0xe 000dfc68 7722198e ntdll!__RtlUserThreadStart+0x23 000dfc80 00000000 ntdll!_RtlUserThreadStart+0x1b
After the call to DnsFreeConfigStructure, dnsapi is never called again