1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-01 21:18:10 +03:00
samba-mirror/source3/libaddns/dnsrequest.c

479 lines
12 KiB
C
Raw Normal View History

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