diff options
Diffstat (limited to 'source3/libaddns/dnsupresp.c')
-rw-r--r-- | source3/libaddns/dnsupresp.c | 397 |
1 files changed, 397 insertions, 0 deletions
diff --git a/source3/libaddns/dnsupresp.c b/source3/libaddns/dnsupresp.c new file mode 100644 index 0000000000..c5f7642acd --- /dev/null +++ b/source3/libaddns/dnsupresp.c @@ -0,0 +1,397 @@ +/* + 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 DNSUpdateAllocateResponse( DNS_UPDATE_RESPONSE ** ppDNSResponse ) +{ + int32 dwError = 0; + DNS_UPDATE_RESPONSE *pDNSResponse = NULL; + + dwError = + DNSAllocateMemory( sizeof( DNS_UPDATE_RESPONSE ), + ( void ** ) &pDNSResponse ); + BAIL_ON_ERROR( dwError ); + + *ppDNSResponse = pDNSResponse; + + return dwError; + + error: + + *ppDNSResponse = NULL; + + return dwError; +} + +/********************************************************************* +*********************************************************************/ + +static int32 DNSUpdateUnmarshallAdditionalSection( 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 *pRRData = 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, &pRRData, + &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 = pRRData; + + *( ppDNSAdditionalRRRecords + i ) = pDNSRRRecord; + } + + error: + + return dwError; +} + +/********************************************************************* +*********************************************************************/ + +static int32 DNSUpdateUnmarshallPRSection( HANDLE hReceiveBuffer, + int16 wPRs, + DNS_RR_RECORD * **pppDNSPRRRRecords ) +{ + int32 dwError = 0; + int32 i = 0; + DNS_RR_RECORD *pDNSRRRecord = NULL; + DNS_RR_RECORD **ppDNSPRRRRecords = NULL; + DNS_RR_HEADER RRHeader = { 0 }; + DNS_RR_HEADER *pRRHeader = &RRHeader; + uint8 *pRRData = NULL; + int32 dwRead = 0; + + dwError = DNSAllocateMemory( wPRs * sizeof( DNS_RR_RECORD * ), + ( void ** ) &ppDNSPRRRRecords ); + BAIL_ON_ERROR( dwError ); + + for ( i = 0; i < wPRs; i++ ) { + + memset( pRRHeader, 0, sizeof( DNS_RR_HEADER ) ); + dwError = DNSUnmarshallRRHeader( hReceiveBuffer, pRRHeader ); + BAIL_ON_ERROR( dwError ); + + dwError = + DNSUnmarshallRData( hReceiveBuffer, + pRRHeader->wRDataSize, &pRRData, + &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 = pRRData; + + *( ppDNSPRRRRecords + i ) = pDNSRRRecord; + } + + *pppDNSPRRRRecords = ppDNSPRRRRecords; + + return dwError; + + error: + + + return dwError; +} + +/********************************************************************* +*********************************************************************/ + +static int32 DNSUpdateUnmarshallUpdateSection( HANDLE hReceiveBuffer, + int16 wUpdates, + DNS_RR_RECORD * **pppDNSUpdateRRRecords ) +{ + int32 dwError = 0; + int32 i = 0; + DNS_RR_RECORD *pDNSRRRecord = NULL; + DNS_RR_RECORD **ppDNSUpdateRRRecords = NULL; + DNS_RR_HEADER RRHeader = { 0 }; + DNS_RR_HEADER *pRRHeader = &RRHeader; + uint8 *pRRData = NULL; + int32 dwRead = 0; + + dwError = DNSAllocateMemory( wUpdates * sizeof( DNS_RR_RECORD * ), + ( void ** ) &ppDNSUpdateRRRecords ); + BAIL_ON_ERROR( dwError ); + + for ( i = 0; i < wUpdates; i++ ) { + + memset( pRRHeader, 0, sizeof( DNS_RR_HEADER ) ); + dwError = DNSUnmarshallRRHeader( hReceiveBuffer, pRRHeader ); + BAIL_ON_ERROR( dwError ); + + dwError = + DNSUnmarshallRData( hReceiveBuffer, + pRRHeader->wRDataSize, &pRRData, + &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 = pRRData; + + *( ppDNSUpdateRRRecords + i ) = pDNSRRRecord; + } + + *pppDNSUpdateRRRecords = ppDNSUpdateRRRecords; + + return dwError; + + error: + + return dwError; + +} + +/********************************************************************* +*********************************************************************/ + +static int32 DNSUpdateUnmarshallZoneSection( HANDLE hReceiveBuffer, + int16 wZones, + DNS_ZONE_RECORD * **pppDNSZoneRecords ) +{ + int32 dwError = 0; + int32 i = 0; + int32 dwRead = 0; + DNS_ZONE_RECORD *pDNSZoneRecord = NULL; + DNS_ZONE_RECORD **ppDNSZoneRecords = NULL; + int16 wnZoneClass = 0; + int16 wnZoneType = 0; + + + dwError = DNSAllocateMemory( wZones * sizeof( DNS_ZONE_RECORD * ), + ( void ** ) &ppDNSZoneRecords ); + BAIL_ON_ERROR( dwError ); + + for ( i = 0; i < wZones; i++ ) { + + dwError = + DNSAllocateMemory( sizeof( DNS_ZONE_RECORD ), + ( void ** ) &pDNSZoneRecord ); + BAIL_ON_ERROR( dwError ); + + dwError = + DNSUnmarshallDomainName( hReceiveBuffer, + &pDNSZoneRecord-> + pDomainName ); + BAIL_ON_ERROR( dwError ); + + dwError = + DNSUnmarshallBuffer( hReceiveBuffer, + ( uint8 * ) & wnZoneType, + ( int32 ) sizeof( int16 ), + &dwRead ); + BAIL_ON_ERROR( dwError ); + pDNSZoneRecord->wZoneType = ntohs( wnZoneType ); + + dwError = + DNSUnmarshallBuffer( hReceiveBuffer, + ( uint8 * ) & wnZoneClass, + ( int32 ) sizeof( int16 ), + &dwRead ); + BAIL_ON_ERROR( dwError ); + pDNSZoneRecord->wZoneClass = ntohs( wnZoneClass ); + + *( ppDNSZoneRecords + i ) = pDNSZoneRecord; + } + + *pppDNSZoneRecords = ppDNSZoneRecords; + return dwError; + + error: + + return dwError; +} + + +/********************************************************************* +*********************************************************************/ + +int32 DNSUpdateReceiveUpdateResponse( HANDLE hDNSHandle, + DNS_UPDATE_RESPONSE ** ppDNSResponse ) +{ + DNS_UPDATE_RESPONSE *pDNSResponse = NULL; + int32 dwError = 0; + int16 wnIdentification, wIdentification = 0; + int16 wnParameter, wParameter = 0; + int16 wnZones, wZones = 0; + int16 wnPRs, wPRs = 0; + int16 wnAdditionals, wAdditionals = 0; + int16 wnUpdates, wUpdates = 0; + int32 dwRead = 0; + DNS_RR_RECORD **ppDNSPRRecords = NULL; + DNS_RR_RECORD **ppDNSAdditionalRecords = NULL; + DNS_RR_RECORD **ppDNSUpdateRecords = NULL; + DNS_ZONE_RECORD **ppDNSZoneRecords = 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 * ) & wnZones, + sizeof( int16 ), &dwRead ); + BAIL_ON_ERROR( dwError ); + wZones = ntohs( wnZones ); + + + dwError = + DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnPRs, + sizeof( int16 ), &dwRead ); + BAIL_ON_ERROR( dwError ); + wPRs = ntohs( wnPRs ); + + + dwError = + DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnUpdates, + sizeof( int16 ), &dwRead ); + BAIL_ON_ERROR( dwError ); + wUpdates = ntohs( wnUpdates ); + + dwError = + DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnAdditionals, + sizeof( int16 ), &dwRead ); + BAIL_ON_ERROR( dwError ); + wAdditionals = ntohs( wnAdditionals ); + + + if ( wZones ) { + dwError = + DNSUpdateUnmarshallZoneSection( hRecvBuffer, wZones, + &ppDNSZoneRecords ); + BAIL_ON_ERROR( dwError ); + } + + if ( wPRs ) { + dwError = + DNSUpdateUnmarshallPRSection( hRecvBuffer, wPRs, + &ppDNSPRRecords ); + BAIL_ON_ERROR( dwError ); + } + + if ( wUpdates ) { + dwError = + DNSUpdateUnmarshallUpdateSection( hRecvBuffer, + wUpdates, + &ppDNSUpdateRecords ); + BAIL_ON_ERROR( dwError ); + } + + if ( wAdditionals ) { + dwError = + DNSUpdateUnmarshallAdditionalSection( hRecvBuffer, + wAdditionals, + &ppDNSAdditionalRecords ); + BAIL_ON_ERROR( dwError ); + } + + dwError = DNSUpdateAllocateResponse( &pDNSResponse ); + BAIL_ON_ERROR( dwError ); + + pDNSResponse->wIdentification = wIdentification; + pDNSResponse->wParameter = wParameter; + pDNSResponse->wZones = wZones; + pDNSResponse->wPRs = wPRs; + pDNSResponse->wUpdates = wUpdates; + pDNSResponse->wAdditionals = wAdditionals; + + pDNSResponse->ppZoneRRSet = ppDNSZoneRecords; + pDNSResponse->ppPRRRSet = ppDNSPRRecords; + pDNSResponse->ppUpdateRRSet = ppDNSUpdateRecords; + pDNSResponse->ppAdditionalRRSet = ppDNSAdditionalRecords; + + *ppDNSResponse = pDNSResponse; + + + error: + + return dwError; +} + |