mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
First push of nslookup implementation.
svn path=/trunk/; revision=43700
This commit is contained in:
parent
1e7aa70379
commit
148016a73d
7 changed files with 1836 additions and 0 deletions
|
@ -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>
|
||||
|
|
858
reactos/base/applications/network/nslookup/nslookup.c
Normal file
858
reactos/base/applications/network/nslookup/nslookup.c
Normal file
|
@ -0,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;
|
||||
}
|
104
reactos/base/applications/network/nslookup/nslookup.h
Normal file
104
reactos/base/applications/network/nslookup/nslookup.h
Normal file
|
@ -0,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 );
|
13
reactos/base/applications/network/nslookup/nslookup.rbuild
Normal file
13
reactos/base/applications/network/nslookup/nslookup.rbuild
Normal file
|
@ -0,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>
|
5
reactos/base/applications/network/nslookup/nslookup.rc
Normal file
5
reactos/base/applications/network/nslookup/nslookup.rc
Normal file
|
@ -0,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>
|
852
reactos/base/applications/network/nslookup/utility.c
Normal file
852
reactos/base/applications/network/nslookup/utility.c
Normal file
|
@ -0,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;
|
||||
}
|
|
@ -64,6 +64,7 @@ base\applications\network\finger\finger.exe 1
|
|||
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
|
||||
|
|
Loading…
Reference in a new issue