summaryrefslogtreecommitdiff
path: root/source3/libaddns/dnsrequest.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libaddns/dnsrequest.c')
-rw-r--r--source3/libaddns/dnsrequest.c478
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;
+}