2006-08-24 19:43:32 +04:00
/*
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 ,
2006-08-25 00:17:59 +04:00
( void * ) & pDNSRequest - > ppQuestionRRSet ,
2006-08-24 19:43:32 +04:00
( 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 ,
2006-08-25 00:17:59 +04:00
( void * ) & pDNSRequest - >
2006-08-24 19:43:32 +04:00
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 ) ,
2006-08-25 00:17:59 +04:00
( void * ) & pDNSRequest ) ;
2006-08-24 19:43:32 +04:00
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 ;
}