diff options
Diffstat (limited to 'source3/libaddns/dnsrequest.c')
-rw-r--r-- | source3/libaddns/dnsrequest.c | 478 |
1 files changed, 478 insertions, 0 deletions
diff --git a/source3/libaddns/dnsrequest.c b/source3/libaddns/dnsrequest.c new file mode 100644 index 0000000000..3dd402981f --- /dev/null +++ b/source3/libaddns/dnsrequest.c @@ -0,0 +1,478 @@ +/* + Linux DNS client library implementation + Copyright (C) 2006 Krishna Ganugapati <krishnag@centeris.com> + Copyright (C) 2006 Gerald Carter <jerry@samba.org> + + ** NOTE! The following LGPL license applies to the libaddns + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "dns.h" + +/********************************************************************* +*********************************************************************/ + +static int32 DNSStdMarshallQuestionSection( HANDLE hSendBuffer, + DNS_QUESTION_RECORD ** ppDNSQuestionRecords, + int16 wQuestions ) +{ + int32 dwError = 0; + int32 i = 0; + int32 dwRead = 0; + DNS_QUESTION_RECORD *pDNSQuestionRecord = NULL; + int16 wnQueryType = 0; + int16 wnQueryClass = 0; + + for ( i = 0; i < wQuestions; i++ ) { + + pDNSQuestionRecord = *( ppDNSQuestionRecords + i ); + dwError = + DNSMarshallDomainName( hSendBuffer, + pDNSQuestionRecord-> + pDomainName ); + BAIL_ON_ERROR( dwError ); + + wnQueryType = htons( pDNSQuestionRecord->wQueryType ); + dwError = + DNSMarshallBuffer( hSendBuffer, + ( uint8 * ) & wnQueryType, + ( int32 ) sizeof( int16 ), + &dwRead ); + BAIL_ON_ERROR( dwError ); + + wnQueryClass = htons( pDNSQuestionRecord->wQueryClass ); + dwError = + DNSMarshallBuffer( hSendBuffer, + ( uint8 * ) & wnQueryClass, + ( int32 ) sizeof( int16 ), + &dwRead ); + BAIL_ON_ERROR( dwError ); + + pDNSQuestionRecord++; + } + + error: + + return dwError; +} + +/********************************************************************* +*********************************************************************/ + +static int32 DNSStdMarshallAnswerSection( HANDLE hSendBuffer, + DNS_RR_RECORD ** ppDNSAnswerRRRecords, + int16 wAnswers ) +{ + int32 dwError = 0; + int32 i = 0; + DNS_RR_RECORD *pDNSAnswerRRRecord = NULL; + + + for ( i = 0; i < wAnswers; i++ ) { + + pDNSAnswerRRRecord = *( ppDNSAnswerRRRecords + i ); + + dwError = + DNSMarshallRRHeader( hSendBuffer, + pDNSAnswerRRRecord ); + BAIL_ON_ERROR( dwError ); + + dwError = DNSMarshallRData( hSendBuffer, pDNSAnswerRRRecord ); + BAIL_ON_ERROR( dwError ); + + pDNSAnswerRRRecord++; + + } + error: + + return dwError; +} + +/********************************************************************* +*********************************************************************/ + +static int32 DNSStdMarshallAuthoritySection( HANDLE hSendBuffer, + DNS_RR_RECORD ** ppDNSAuthorityRRRecords, + int16 wAuthoritys ) +{ + int32 dwError = 0; + int32 i = 0; + + DNS_RR_RECORD *pDNSAuthorityRRRecord = NULL; + + for ( i = 0; i < wAuthoritys; i++ ) { + + pDNSAuthorityRRRecord = *( ppDNSAuthorityRRRecords + i ); + + dwError = + DNSMarshallRRHeader( hSendBuffer, + pDNSAuthorityRRRecord ); + + dwError = DNSMarshallRData( hSendBuffer, + pDNSAuthorityRRRecord ); + BAIL_ON_ERROR( dwError ); + + } + error: + + return dwError; +} + +/********************************************************************* +*********************************************************************/ + +static int32 DNSStdMarshallAdditionalSection( HANDLE hSendBuffer, + DNS_RR_RECORD ** ppDNSAdditionalsRRRecords, + int16 wAdditionals ) +{ + int32 dwError = 0; + int32 i = 0; + DNS_RR_RECORD *pDNSAdditionalRRRecord = NULL; + + for ( i = 0; i < wAdditionals; i++ ) { + + pDNSAdditionalRRRecord = *( ppDNSAdditionalsRRRecords + i ); + + dwError = + DNSMarshallRRHeader( hSendBuffer, + pDNSAdditionalRRRecord ); + BAIL_ON_ERROR( dwError ); + + dwError = DNSMarshallRData( hSendBuffer, + pDNSAdditionalRRRecord ); + BAIL_ON_ERROR( dwError ); + + } + + error: + + return dwError; +} + +/********************************************************************* +*********************************************************************/ + +static int32 DNSBuildRequestMessage( DNS_REQUEST * pDNSRequest, HANDLE * phSendBuffer ) +{ + int32 dwError = 0; + char DNSMessageHeader[12]; + int16 wnIdentification = 0; + int16 wnParameter = 0; + int16 wnQuestions = 0; + int16 wnAnswers = 0; + int16 wnAuthoritys = 0; + int16 wnAdditionals = 0; + int32 dwRead = 0; + HANDLE hSendBuffer = ( HANDLE ) NULL; + + dwError = DNSCreateSendBuffer( &hSendBuffer ); + BAIL_ON_ERROR( dwError ); + + wnIdentification = htons( pDNSRequest->wIdentification ); + memcpy( DNSMessageHeader, ( char * ) &wnIdentification, 2 ); + + wnParameter = htons( pDNSRequest->wParameter ); + memcpy( DNSMessageHeader + 2, ( char * ) &wnParameter, 2 ); + + wnQuestions = htons( pDNSRequest->wQuestions ); + memcpy( DNSMessageHeader + 4, ( char * ) &wnQuestions, 2 ); + + wnAnswers = htons( pDNSRequest->wAnswers ); + memcpy( DNSMessageHeader + 6, ( char * ) &wnAnswers, 2 ); + + wnAuthoritys = htons( pDNSRequest->wAuthoritys ); + memcpy( DNSMessageHeader + 8, ( char * ) &wnAuthoritys, 2 ); + + wnAdditionals = htons( pDNSRequest->wAdditionals ); + memcpy( DNSMessageHeader + 10, ( char * ) &wnAdditionals, 2 ); + + dwError = + DNSMarshallBuffer( hSendBuffer, ( uint8 * ) DNSMessageHeader, + 12, &dwRead ); + BAIL_ON_ERROR( dwError ); + + if ( pDNSRequest->wQuestions ) { + dwError = + DNSStdMarshallQuestionSection( hSendBuffer, + pDNSRequest-> + ppQuestionRRSet, + pDNSRequest-> + wQuestions ); + BAIL_ON_ERROR( dwError ); + } + + if ( pDNSRequest->wAnswers ) { + dwError = + DNSStdMarshallAnswerSection( hSendBuffer, + pDNSRequest-> + ppAnswerRRSet, + pDNSRequest->wAnswers ); + BAIL_ON_ERROR( dwError ); + } + + if ( pDNSRequest->wAuthoritys ) { + dwError = + DNSStdMarshallAuthoritySection( hSendBuffer, + pDNSRequest-> + ppAuthorityRRSet, + pDNSRequest-> + wAuthoritys ); + BAIL_ON_ERROR( dwError ); + } + + if ( pDNSRequest->wAdditionals ) { + dwError = + DNSStdMarshallAdditionalSection( hSendBuffer, + pDNSRequest-> + ppAdditionalRRSet, + pDNSRequest-> + wAdditionals ); + BAIL_ON_ERROR( dwError ); + } +#if 0 + DNSDumpSendBufferContext( hSendBuffer ); +#endif + *phSendBuffer = hSendBuffer; + + return dwError; + + error: + + if ( hSendBuffer ) { + DNSFreeSendBufferContext( hSendBuffer ); + } + + *phSendBuffer = ( HANDLE ) NULL; + return dwError; +} + +/********************************************************************* +*********************************************************************/ + +int32 DNSStdSendStdRequest2( HANDLE hDNSServer, DNS_REQUEST * pDNSRequest ) +{ + int32 dwError = 0; + int32 dwBytesSent = 0; + HANDLE hSendBuffer = ( HANDLE ) NULL; + + dwError = DNSBuildRequestMessage( pDNSRequest, &hSendBuffer ); + BAIL_ON_ERROR( dwError ); + + dwError = + DNSSendBufferContext( hDNSServer, hSendBuffer, &dwBytesSent ); + BAIL_ON_ERROR( dwError ); + + error: + + if ( hSendBuffer ) { + DNSFreeSendBufferContext( hSendBuffer ); + } + + return dwError; +} + +/********************************************************************* +*********************************************************************/ + +int32 DNSMarshallDomainName( HANDLE hSendBuffer, DNS_DOMAIN_NAME * pDomainName ) +{ + int32 dwError = 0; + DNS_DOMAIN_LABEL *pTemp = NULL; + int32 dwLen = 0; + int32 dwSent = 0; + char uEndChar = 0; + + pTemp = pDomainName->pLabelList; + while ( pTemp ) { + dwLen = ( int32 ) strlen( pTemp->pszLabel ); + dwError = + DNSMarshallBuffer( hSendBuffer, ( uint8 * ) & dwLen, + sizeof( char ), &dwSent ); + BAIL_ON_ERROR( dwError ); + + dwError = + DNSMarshallBuffer( hSendBuffer, + ( uint8 * ) pTemp->pszLabel, dwLen, + &dwSent ); + BAIL_ON_ERROR( dwError ); + pTemp = pTemp->pNext; + } + DNSMarshallBuffer( hSendBuffer, ( uint8 * ) & uEndChar, + sizeof( char ), &dwSent ); + + error: + + return dwError; +} + +/********************************************************************* +*********************************************************************/ + +int32 DNSMarshallRRHeader( HANDLE hSendBuffer, DNS_RR_RECORD * pDNSRecord ) +{ + int32 dwError = 0; + int32 dwRead = 0; + int16 wnType = 0; + int16 wnClass = 0; + int16 wnRDataSize = 0; + int32 dwnTTL = 0; + + dwError = + DNSMarshallDomainName( hSendBuffer, + pDNSRecord->RRHeader.pDomainName ); + BAIL_ON_ERROR( dwError ); + + wnType = htons( pDNSRecord->RRHeader.wType ); + dwError = + DNSMarshallBuffer( hSendBuffer, ( uint8 * ) & wnType, + sizeof( int16 ), &dwRead ); + BAIL_ON_ERROR( dwError ); + + wnClass = htons( pDNSRecord->RRHeader.wClass ); + dwError = + DNSMarshallBuffer( hSendBuffer, ( uint8 * ) & wnClass, + sizeof( int16 ), &dwRead ); + BAIL_ON_ERROR( dwError ); + + dwnTTL = htonl( pDNSRecord->RRHeader.dwTTL ); + dwError = + DNSMarshallBuffer( hSendBuffer, ( uint8 * ) & dwnTTL, + sizeof( int32 ), &dwRead ); + BAIL_ON_ERROR( dwError ); + + wnRDataSize = htons( pDNSRecord->RRHeader.wRDataSize ); + dwError = + DNSMarshallBuffer( hSendBuffer, ( uint8 * ) & wnRDataSize, + sizeof( int16 ), &dwRead ); + BAIL_ON_ERROR( dwError ); + + error: + + return dwError; +} + +/********************************************************************* +*********************************************************************/ + +int32 DNSMarshallRData( HANDLE hSendBuffer, DNS_RR_RECORD * pDNSRecord ) +{ + int32 dwError = 0; + int32 dwWritten = 0; + + dwError = + DNSMarshallBuffer( hSendBuffer, pDNSRecord->pRData, + pDNSRecord->RRHeader.wRDataSize, + &dwWritten ); + BAIL_ON_ERROR( dwError ); + + error: + + return dwError; +} + +/********************************************************************* +*********************************************************************/ + +int32 DNSStdAddQuestionSection( DNS_REQUEST * pDNSRequest, + DNS_QUESTION_RECORD * pDNSQuestion ) +{ + int32 dwNumQuestions = 0; + int32 dwError = 0; + + dwNumQuestions = pDNSRequest->wQuestions; + + dwError = DNSReallocMemory( ( uint8 * ) pDNSRequest->ppQuestionRRSet, + ( void ** ) &pDNSRequest->ppQuestionRRSet, + ( dwNumQuestions + + 1 ) * sizeof( DNS_QUESTION_RECORD * ) + ); + BAIL_ON_ERROR( dwError ); + + *( pDNSRequest->ppQuestionRRSet + dwNumQuestions ) = pDNSQuestion; + + pDNSRequest->wQuestions += 1; + + error: + + return dwError; +} + +/********************************************************************* +*********************************************************************/ + +int32 DNSStdAddAdditionalSection( DNS_REQUEST * pDNSRequest, + DNS_RR_RECORD * pDNSRecord ) +{ + int32 dwNumAdditionals = 0; + int32 dwError = 0; + + dwNumAdditionals = pDNSRequest->wAdditionals; + dwError = DNSReallocMemory( pDNSRequest->ppAdditionalRRSet, + ( void ** ) &pDNSRequest-> + ppAdditionalRRSet, + ( dwNumAdditionals + + 1 ) * sizeof( DNS_RR_RECORD * ) ); + BAIL_ON_ERROR( dwError ); + + *( pDNSRequest->ppAdditionalRRSet + dwNumAdditionals ) = pDNSRecord; + + pDNSRequest->wAdditionals += 1; + + error: + return dwError; +} + +/********************************************************************* +*********************************************************************/ + +int32 DNSStdCreateStdRequest( DNS_REQUEST ** ppDNSRequest ) +{ + int32 dwError = 0; + DNS_REQUEST *pDNSRequest = NULL; + +#if 0 + int16 wRecursionDesired = RECURSION_DESIRED; + int16 wParameter = QR_QUERY; + int16 wOpcode = OPCODE_QUERY; +#endif + dwError = + DNSAllocateMemory( sizeof( DNS_REQUEST ), + ( void ** ) &pDNSRequest ); + BAIL_ON_ERROR( dwError ); + + dwError = DNSGenerateIdentifier( &pDNSRequest->wIdentification ); + BAIL_ON_ERROR( dwError ); + +/* + wOpcode <<= 1; + wRecursionDesired <<= 7; + wParameter |= wOpcode; + wParameter |= wRecursionDesired; +*/ + pDNSRequest->wParameter = 0x00; + + *ppDNSRequest = pDNSRequest; + + return dwError; + + error: + + *ppDNSRequest = NULL; + return dwError; +} |