ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

void PerformLookup ( PCHAR  pAddr)

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;
}

Generated on Sat May 26 2012 04:41:29 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.