Home | Info | Community | Development | myReactOS | Contact Us
Definition at line 233 of file nslookup.c.
Referenced by ParseCommandLine().
{ /* 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 Header2; USHORT NumQuestions; USHORT NumAnswers; USHORT NumAuthority; 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. */ Header2 = RecBuffer[3]; NumQuestions = ntohs( ((PSHORT)&RecBuffer[4])[0] ); NumAnswers = ntohs( ((PSHORT)&RecBuffer[6])[0] ); NumAuthority = ntohs( ((PUSHORT)&RecBuffer[8])[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; }