summaryrefslogtreecommitdiff
path: root/source3/libaddns/dnsresponse.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libaddns/dnsresponse.c')
-rw-r--r--source3/libaddns/dnsresponse.c589
1 files changed, 589 insertions, 0 deletions
diff --git a/source3/libaddns/dnsresponse.c b/source3/libaddns/dnsresponse.c
new file mode 100644
index 0000000000..65a8853049
--- /dev/null
+++ b/source3/libaddns/dnsresponse.c
@@ -0,0 +1,589 @@
+/*
+ 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 DNSStdAllocateResponse( DNS_RESPONSE ** ppDNSResponse )
+{
+ int32 dwError = 0;
+ DNS_RESPONSE *pDNSResponse = NULL;
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RESPONSE ),
+ ( void ** ) &pDNSResponse );
+ BAIL_ON_ERROR( dwError );
+
+ *ppDNSResponse = pDNSResponse;
+
+ return dwError;
+
+ error:
+
+ *ppDNSResponse = NULL;
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSStdUnmarshallQuestionSection( HANDLE hReceiveBuffer,
+ int16 wQuestions,
+ DNS_QUESTION_RECORD *
+ **pppDNSQuestionRecords )
+{
+ int32 dwError = 0;
+ int32 i = 0;
+ int32 dwRead = 0;
+ DNS_QUESTION_RECORD *pDNSQuestionRecord = NULL;
+ DNS_QUESTION_RECORD **ppDNSQuestionRecords = NULL;
+ int16 wnQueryClass = 0;
+ int16 wnQueryType = 0;
+
+
+ dwError =
+ DNSAllocateMemory( wQuestions *
+ sizeof( DNS_QUESTION_RECORD * ),
+ ( void ** ) &ppDNSQuestionRecords );
+ BAIL_ON_ERROR( dwError );
+
+ for ( i = 0; i < wQuestions; i++ ) {
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_QUESTION_RECORD ),
+ ( void ** ) &pDNSQuestionRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUnmarshallDomainName( hReceiveBuffer,
+ &pDNSQuestionRecord->
+ pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUnmarshallBuffer( hReceiveBuffer,
+ ( uint8 * ) & wnQueryType,
+ ( int32 ) sizeof( int16 ),
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+ pDNSQuestionRecord->wQueryType = ntohs( wnQueryType );
+
+ dwError =
+ DNSUnmarshallBuffer( hReceiveBuffer,
+ ( uint8 * ) & wnQueryClass,
+ ( int32 ) sizeof( int16 ),
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+ pDNSQuestionRecord->wQueryClass = ntohs( wnQueryClass );
+
+ *( ppDNSQuestionRecords + i ) = pDNSQuestionRecord;
+ }
+
+ *pppDNSQuestionRecords = ppDNSQuestionRecords;
+ return dwError;
+
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSStdUnmarshallAnswerSection( HANDLE hReceiveBuffer,
+ int16 wAnswers,
+ DNS_RR_RECORD * **pppDNSAnswerRRRecords )
+{
+ int32 dwError = 0;
+ int32 i = 0;
+ DNS_RR_RECORD *pDNSRRRecord = NULL;
+ DNS_RR_RECORD **ppDNSAnswerRRRecords = NULL;
+ DNS_RR_HEADER RRHeader = { 0 };
+ DNS_RR_HEADER *pRRHeader = &RRHeader;
+ uint8 *pRData = NULL;
+ int32 dwRead = 0;
+
+ dwError = DNSAllocateMemory( wAnswers * sizeof( DNS_RR_RECORD * ),
+ ( void ** ) &ppDNSAnswerRRRecords );
+ BAIL_ON_ERROR( dwError );
+
+ for ( i = 0; i < wAnswers; i++ ) {
+
+ memset( pRRHeader, 0, sizeof( DNS_RR_HEADER ) );
+ dwError = DNSUnmarshallRRHeader( hReceiveBuffer, pRRHeader );
+ BAIL_ON_ERROR( dwError );
+
+
+ dwError =
+ DNSUnmarshallRData( hReceiveBuffer,
+ pRRHeader->wRDataSize, &pRData,
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ memcpy( &pDNSRRRecord->RRHeader, pRRHeader,
+ sizeof( DNS_RR_HEADER ) );
+ pDNSRRRecord->pRData = pRData;
+
+ *( ppDNSAnswerRRRecords + i ) = pDNSRRRecord;
+ }
+
+ *pppDNSAnswerRRRecords = ppDNSAnswerRRRecords;
+
+ return dwError;
+
+ error:
+
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSStdUnmarshallAuthoritySection( HANDLE hReceiveBuffer,
+ int16 wAuthoritys,
+ DNS_RR_RECORD * **pppDNSAuthorityRRRecords )
+{
+ int32 dwError = 0;
+ int32 i = 0;
+ DNS_RR_RECORD *pDNSRRRecord = NULL;
+ DNS_RR_RECORD **ppDNSAuthorityRRRecords = NULL;
+ DNS_RR_HEADER RRHeader = { 0 };
+ DNS_RR_HEADER *pRRHeader = &RRHeader;
+ uint8 *pRData = NULL;
+ int32 dwRead = 0;
+
+ dwError = DNSAllocateMemory( wAuthoritys * sizeof( DNS_RR_RECORD * ),
+ ( void ** ) &ppDNSAuthorityRRRecords );
+ BAIL_ON_ERROR( dwError );
+
+ for ( i = 0; i < wAuthoritys; i++ ) {
+
+ memset( pRRHeader, 0, sizeof( DNS_RR_HEADER ) );
+ dwError = DNSUnmarshallRRHeader( hReceiveBuffer, pRRHeader );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUnmarshallRData( hReceiveBuffer,
+ pRRHeader->wRDataSize, &pRData,
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ memcpy( &pDNSRRRecord->RRHeader, pRRHeader,
+ sizeof( DNS_RR_HEADER ) );
+ pDNSRRRecord->pRData = pRData;
+
+ *( ppDNSAuthorityRRRecords + i ) = pDNSRRRecord;
+ }
+
+ *pppDNSAuthorityRRRecords = ppDNSAuthorityRRRecords;
+
+ return dwError;
+
+ error:
+
+ return dwError;
+
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSStdUnmarshallAdditionalSection( HANDLE hReceiveBuffer,
+ int16 wAdditionals,
+ DNS_RR_RECORD *
+ **pppDNSAdditionalsRRRecords )
+{
+ int32 dwError = 0;
+ int32 i = 0;
+ DNS_RR_RECORD *pDNSRRRecord = NULL;
+ DNS_RR_RECORD **ppDNSAdditionalRRRecords = NULL;
+ DNS_RR_HEADER RRHeader = { 0 };
+ DNS_RR_HEADER *pRRHeader = &RRHeader;
+ uint8 *pRData = NULL;
+ int32 dwRead = 0;
+
+ dwError = DNSAllocateMemory( wAdditionals * sizeof( DNS_RR_RECORD * ),
+ ( void ** ) &ppDNSAdditionalRRRecords );
+ BAIL_ON_ERROR( dwError );
+
+ for ( i = 0; i < wAdditionals; i++ ) {
+
+ memset( pRRHeader, 0, sizeof( DNS_RR_HEADER ) );
+ dwError = DNSUnmarshallRRHeader( hReceiveBuffer, pRRHeader );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUnmarshallRData( hReceiveBuffer,
+ pRRHeader->wRDataSize, &pRData,
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ memcpy( &pDNSRRRecord->RRHeader, pRRHeader,
+ sizeof( DNS_RR_HEADER ) );
+ pDNSRRRecord->pRData = pRData;
+
+
+ *( ppDNSAdditionalRRRecords + i ) = pDNSRRRecord;
+ }
+
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSStdReceiveStdResponse( HANDLE hDNSHandle, DNS_RESPONSE ** ppDNSResponse )
+{
+ DNS_RESPONSE *pDNSResponse = NULL;
+ int32 dwError = 0;
+ int16 wnIdentification, wIdentification = 0;
+ int16 wnParameter, wParameter = 0;
+ int16 wnQuestions, wQuestions = 0;
+ int16 wnAnswers, wAnswers = 0;
+ int16 wnAdditionals, wAdditionals = 0;
+ int16 wnAuthoritys, wAuthoritys = 0;
+ int32 dwRead = 0;
+ DNS_RR_RECORD **ppDNSAnswerRecords = NULL;
+ DNS_RR_RECORD **ppDNSAdditionalRecords = NULL;
+ DNS_RR_RECORD **ppDNSAuthorityRecords = NULL;
+ DNS_QUESTION_RECORD **ppDNSQuestionRecords = NULL;
+ HANDLE hRecvBuffer = ( HANDLE ) NULL;
+
+ dwError = DNSCreateReceiveBuffer( &hRecvBuffer );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSReceiveBufferContext( hDNSHandle, hRecvBuffer, &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+#if 0
+ dwError = DNSDumpRecvBufferContext( hRecvBuffer );
+ BAIL_ON_ERROR( dwError );
+#endif
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer,
+ ( uint8 * ) & wnIdentification,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ wIdentification = ntohs( wnIdentification );
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnParameter,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ wParameter = ntohs( wnParameter );
+
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnQuestions,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ wQuestions = ntohs( wnQuestions );
+
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnAnswers,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ wAnswers = ntohs( wnAnswers );
+
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnAuthoritys,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ wAuthoritys = ntohs( wnAuthoritys );
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnAdditionals,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ wAdditionals = ntohs( wnAdditionals );
+
+
+ if ( wQuestions ) {
+ dwError =
+ DNSStdUnmarshallQuestionSection( hRecvBuffer,
+ wQuestions,
+ &ppDNSQuestionRecords );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ if ( wAnswers ) {
+ dwError =
+ DNSStdUnmarshallAnswerSection( hRecvBuffer, wAnswers,
+ &ppDNSAnswerRecords );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ if ( wAuthoritys ) {
+ dwError =
+ DNSStdUnmarshallAuthoritySection( hRecvBuffer,
+ wAuthoritys,
+ &ppDNSAuthorityRecords );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ if ( wAdditionals ) {
+ dwError =
+ DNSStdUnmarshallAdditionalSection( hRecvBuffer,
+ wAdditionals,
+ &ppDNSAdditionalRecords );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ dwError = DNSStdAllocateResponse( &pDNSResponse );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSResponse->wIdentification = wIdentification;
+ pDNSResponse->wParameter = wParameter;
+ pDNSResponse->wQuestions = wQuestions;
+ pDNSResponse->wAnswers = wAnswers;
+ pDNSResponse->wAuthoritys = wAuthoritys;
+ pDNSResponse->wAdditionals = wAdditionals;
+
+ pDNSResponse->ppQuestionRRSet = ppDNSQuestionRecords;
+ pDNSResponse->ppAnswerRRSet = ppDNSAnswerRecords;
+ pDNSResponse->ppAuthorityRRSet = ppDNSAuthorityRecords;
+ pDNSResponse->ppAdditionalRRSet = ppDNSAdditionalRecords;
+
+ *ppDNSResponse = pDNSResponse;
+
+
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSUnmarshallDomainName( HANDLE hRecvBuffer, DNS_DOMAIN_NAME ** ppDomainName )
+{
+ int32 dwError = 0;
+ DNS_DOMAIN_LABEL *pLabel = NULL;
+ DNS_DOMAIN_LABEL *pLabelList = NULL;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+ char *pszLabel = NULL;
+ char szLabel[65];
+ uint8 uLen = 0;
+ int32 dwRead = 0;
+ uint8 uLen1, uLen2 = 0;
+ int16 wnOffset, wOffset = 0;
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, &uLen1, sizeof( char ),
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+ if ( uLen1 & 0xC0 ) {
+
+ uLen1 |= 0x3F;
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, &uLen2,
+ sizeof( char ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ memcpy( ( uint8 * ) & wnOffset, &uLen1, sizeof( char ) );
+ memcpy( ( uint8 * ) & wnOffset + 1, &uLen2, sizeof( char ) );
+ wOffset = ntohs( wnOffset );
+
+ dwError =
+ DNSUnmarshallDomainNameAtOffset( hRecvBuffer, wOffset,
+ &pDomainName );
+ BAIL_ON_ERROR( dwError );
+ *ppDomainName = pDomainName;
+
+ return dwError;
+
+ } else {
+
+ dwError = DNSReceiveBufferMoveBackIndex( hRecvBuffer, 1 );
+ BAIL_ON_ERROR( dwError );
+
+ while ( 1 ) {
+
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, &uLen,
+ sizeof( char ),
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+ if ( uLen == 0 ) {
+ break;
+ }
+
+ memset( szLabel, 0, 65 );
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer,
+ ( uint8 * ) szLabel,
+ uLen, &dwRead );
+
+ dwError = DNSAllocateString( szLabel, &pszLabel );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_DOMAIN_LABEL ),
+ ( void ** ) &pLabel );
+ BAIL_ON_ERROR( dwError );
+
+ pLabel->pszLabel = pszLabel;
+ dwError =
+ DNSAppendLabel( pLabelList, pLabel,
+ &pLabelList );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ }
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_DOMAIN_NAME ),
+ ( void ** ) &pDomainName );
+ BAIL_ON_ERROR( dwError );
+ pDomainName->pLabelList = pLabelList;
+
+ *ppDomainName = pDomainName;
+
+ return dwError;
+
+ error:
+
+ *ppDomainName = NULL;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSUnmarshallRRHeader( HANDLE hRecvBuffer, DNS_RR_HEADER * pRRHeader )
+{
+ int32 dwError = 0;
+ int32 dwRead = 0;
+ int16 wnType = 0;
+ int16 wnClass = 0;
+ int16 wnRDataSize = 0;
+ int32 dwnTTL = 0;
+
+ dwError =
+ DNSUnmarshallDomainName( hRecvBuffer,
+ &pRRHeader->pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnType,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ pRRHeader->wType = ntohs( wnType );
+
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnClass,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ pRRHeader->wClass = ntohs( wnClass );
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & dwnTTL,
+ sizeof( int32 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ pRRHeader->dwTTL = ntohl( dwnTTL );
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnRDataSize,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ pRRHeader->wRDataSize = htons( wnRDataSize );
+
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSUnmarshallRData( HANDLE hRecvBuffer,
+ int32 dwSize, uint8 ** ppRData, int32 * pdwRead )
+{
+ int32 dwError = 0;
+ uint8 *pMemory = NULL;
+
+ dwError = DNSAllocateMemory( dwSize, ( void ** ) &pMemory );
+ BAIL_ON_ERROR( dwError );
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) pMemory, dwSize,
+ pdwRead );
+ BAIL_ON_ERROR( dwError );
+
+ *ppRData = pMemory;
+
+ return dwError;
+
+ error:
+
+ if ( pMemory ) {
+ DNSFreeMemory( pMemory );
+ }
+
+ *ppRData = NULL;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSUpdateGetResponseCode( DNS_UPDATE_RESPONSE * pDNSUpdateResponse,
+ int32 * pdwResponseCode )
+{
+ int32 dwError = 0;
+
+ *pdwResponseCode =
+ MapDNSResponseCodes( pDNSUpdateResponse->wParameter );
+
+ return dwError;
+}
+