summaryrefslogtreecommitdiff
path: root/source3/libaddns/dnssock.c
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2006-08-24 15:43:32 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:38:48 -0500
commit5693e6c599a586b1bb19eea375c6b1e22526031c (patch)
tree9190fcd83791a892aaca33debd400fd0b4124fc2 /source3/libaddns/dnssock.c
parent6717e0d467bea50cb7712e6b5278ddb403fdf828 (diff)
downloadsamba-5693e6c599a586b1bb19eea375c6b1e22526031c.tar.gz
samba-5693e6c599a586b1bb19eea375c6b1e22526031c.tar.bz2
samba-5693e6c599a586b1bb19eea375c6b1e22526031c.zip
r17798: Beginnings of a standalone libaddns library released under
the LGPL. Original code by Krishna Ganugapati <krishnag@centeris.com>. Additional work by me. It's still got some warts, but non-secure updates do currently work. There are at least four things left to really clean up. 1. Change the memory management to use talloc() rather than malloc() and cleanup the leaks. 2. Fix the error code reporting (see initial changes to dnserr.h) 3. Fix the secure updates 4. Define a public interface in addns.h 5. Move the code in libads/dns.c into the libaddns/ directory (and under the LGPL). A few notes: * Enable the new code by compiling with --with-dnsupdate * Also adds the command 'net ads dns register' * Requires -luuid (included in the e2fsprogs-devel package). * Has only been tested on Linux platforms so there may be portability issues. (This used to be commit 36f04674aeefd93c5a0408b8967dcd48b86fdbc1)
Diffstat (limited to 'source3/libaddns/dnssock.c')
-rw-r--r--source3/libaddns/dnssock.c766
1 files changed, 766 insertions, 0 deletions
diff --git a/source3/libaddns/dnssock.c b/source3/libaddns/dnssock.c
new file mode 100644
index 0000000000..0af30cc1be
--- /dev/null
+++ b/source3/libaddns/dnssock.c
@@ -0,0 +1,766 @@
+/*
+ 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 DNS_ERROR DNSTCPOpen( char *nameserver, HANDLE * phDNSServer )
+{
+ DNS_ERROR dwError = ERROR_DNS_INVALID_PARAMETER;
+ int sockServer;
+ unsigned long ulAddress;
+ struct hostent *pHost;
+ struct sockaddr_in s_in;
+ DNS_CONNECTION_CONTEXT *pDNSContext = NULL;
+
+ if ( (pDNSContext = TALLOC_P( NULL, DNS_CONNECTION_CONTEXT )) == NULL ) {
+ return ERROR_DNS_NO_MEMORY;
+ }
+
+ if ( (ulAddress = inet_addr( nameserver )) == INADDR_NONE ) {
+ if ( (pHost = gethostbyname( nameserver )) == NULL ) {
+ dwError = ERROR_DNS_INVALID_NAME_SERVER;
+ BAIL_ON_DNS_ERROR( dwError );
+ }
+ memcpy( &ulAddress, pHost->h_addr, pHost->h_length );
+ }
+
+ if ( (sockServer = socket( PF_INET, SOCK_STREAM, 0 )) == INVALID_SOCKET ) {
+ dwError = ERROR_DNS_NO_MEMORY;
+ BAIL_ON_DNS_ERROR( dwError );
+ }
+
+ s_in.sin_family = AF_INET;
+ s_in.sin_addr.s_addr = ulAddress;
+ s_in.sin_port = htons( DNS_TCP_PORT );
+
+ if ( (connect( sockServer, &s_in, sizeof( s_in ))) == SOCKET_ERROR ) {
+ dwError = ERROR_DNS_CONNECTION_FAILED;
+ BAIL_ON_DNS_ERROR( dwError );
+ }
+
+ pDNSContext->s = sockServer;
+ pDNSContext->hType = DNS_TCP;
+
+ *phDNSServer = ( HANDLE ) pDNSContext;
+
+ dwError = ERROR_DNS_SUCCESS;
+
+ return dwError;
+
+error:
+ TALLOC_FREE( pDNSContext );
+ *phDNSServer = ( HANDLE ) NULL;
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+static DNS_ERROR DNSUDPOpen( char *nameserver, HANDLE * phDNSServer )
+{
+ DNS_ERROR dwError = ERROR_DNS_INVALID_PARAMETER;
+ int SendSocket;
+ unsigned long ulAddress;
+ struct hostent *pHost;
+ struct sockaddr_in RecvAddr;
+ DNS_CONNECTION_CONTEXT *pDNSContext = NULL;
+
+ if ( (pDNSContext = TALLOC_P( NULL, DNS_CONNECTION_CONTEXT )) == NULL ) {
+ return ERROR_DNS_NO_MEMORY;
+ }
+
+ if ( (ulAddress = inet_addr( nameserver )) == INADDR_NONE ) {
+ if ( (pHost = gethostbyname( nameserver )) == NULL ) {
+ dwError = ERROR_DNS_INVALID_NAME_SERVER;
+ BAIL_ON_DNS_ERROR( dwError );
+ }
+ memcpy( &ulAddress, pHost->h_addr, pHost->h_length );
+ }
+
+ /* Create a socket for sending data */
+
+ SendSocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
+
+ /* Set up the RecvAddr structure with the IP address of
+ the receiver (in this example case "123.456.789.1")
+ and the specified port number. */
+
+ RecvAddr.sin_family = AF_INET;
+ RecvAddr.sin_port = htons( DNS_UDP_PORT );
+ RecvAddr.sin_addr.s_addr = ulAddress;
+
+ pDNSContext->s = SendSocket;
+ pDNSContext->hType = DNS_UDP;
+ memcpy( &pDNSContext->RecvAddr, &RecvAddr, sizeof( struct sockaddr_in ) );
+
+ *phDNSServer = ( HANDLE ) pDNSContext;
+
+ dwError = ERROR_DNS_SUCCESS;
+
+ return dwError;
+
+error:
+ TALLOC_FREE( pDNSContext );
+ *phDNSServer = ( HANDLE ) NULL;
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+DNS_ERROR DNSOpen( char *nameserver, int32 dwType, HANDLE * phDNSServer )
+{
+ switch ( dwType ) {
+ case DNS_TCP:
+ return DNSTCPOpen( nameserver, phDNSServer );
+ case DNS_UDP:
+ return DNSUDPOpen( nameserver, phDNSServer );
+ }
+
+ return ERROR_DNS_INVALID_PARAMETER;
+}
+
+/********************************************************************
+********************************************************************/
+
+static int32 DNSSendTCPRequest( HANDLE hDNSHandle,
+ uint8 * pDNSSendBuffer,
+ int32 dwBufferSize, int32 * pdwBytesSent )
+{
+ int32 dwError = 0;
+ int32 dwBytesSent = 0;
+ DNS_CONNECTION_CONTEXT *pDNSContext = NULL;
+
+
+ pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle;
+
+ dwBytesSent = send( pDNSContext->s, pDNSSendBuffer, dwBufferSize, 0 );
+ if ( dwBytesSent == SOCKET_ERROR ) {
+ dwError = WSAGetLastError( );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ *pdwBytesSent = dwBytesSent;
+
+ return dwError;
+
+ error:
+ *pdwBytesSent = 0;
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+static int32 DNSSendUDPRequest( HANDLE hDNSHandle,
+ uint8 * pDNSSendBuffer,
+ int32 dwBufferSize, int32 * pdwBytesSent )
+{
+ int32 dwError = 0;
+ int32 dwBytesSent = 0;
+ DNS_CONNECTION_CONTEXT *pDNSContext = NULL;
+
+ pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle;
+
+ dwBytesSent = sendto( pDNSContext->s,
+ pDNSSendBuffer,
+ dwBufferSize,
+ 0,
+ ( struct sockaddr * ) & pDNSContext->RecvAddr,
+ sizeof( pDNSContext->RecvAddr )
+ );
+ if ( dwBytesSent == SOCKET_ERROR ) {
+ dwError = WSAGetLastError( );
+ BAIL_ON_ERROR( dwError );
+ } else {
+ *pdwBytesSent = dwBytesSent;
+ }
+
+ return dwError;
+
+ error:
+ *pdwBytesSent = 0;
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+static int32 DNSSelect( HANDLE hDNSHandle )
+{
+ int32 dwError = 0;
+ fd_set rfds;
+ struct timeval tv;
+ int32 dwNumSockets = 0;
+ DNS_CONNECTION_CONTEXT *pDNSContext = NULL;
+
+ pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle;
+ FD_ZERO( &rfds );
+ FD_SET( pDNSContext->s, &rfds );
+
+ tv.tv_sec = 10;
+ tv.tv_usec = 0;
+ dwNumSockets = select( pDNSContext->s + 1, &rfds, NULL, NULL, &tv );
+ if ( dwNumSockets == SOCKET_ERROR ) {
+ dwError = WSAGetLastError( );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ if ( !dwNumSockets ) {
+#ifndef WIN32
+ dwError = ETIMEDOUT;
+#elif
+ dwError = WSAETIMEDOUT;
+#endif
+ }
+
+ error:
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+static int32 DNSTCPReceiveBufferContext( HANDLE hDNSHandle,
+ HANDLE hDNSRecvBuffer, int32 * pdwBytesRead )
+{
+ int32 dwError = 0;
+ int32 dwRead = 0;
+ int16 wBytesToRead = 0;
+ int16 wnBytesToRead = 0;
+ DNS_CONNECTION_CONTEXT *pDNSContext = NULL;
+ DNS_RECEIVEBUFFER_CONTEXT *pDNSRecvContext = NULL;
+
+ pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle;
+ pDNSRecvContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hDNSRecvBuffer;
+
+ dwError = DNSSelect( hDNSHandle );
+ BAIL_ON_ERROR( dwError );
+
+ dwRead = recv( pDNSContext->s, ( char * ) &wnBytesToRead,
+ sizeof( int16 ), 0 );
+ if ( dwRead == SOCKET_ERROR ) {
+ dwError = WSAGetLastError( );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ wBytesToRead = ntohs( wnBytesToRead );
+
+ dwError = DNSSelect( hDNSHandle );
+ BAIL_ON_ERROR( dwError );
+
+ dwRead = recv( pDNSContext->s,
+ ( char * ) pDNSRecvContext->pRecvBuffer, wBytesToRead,
+ 0 );
+ if ( dwRead == SOCKET_ERROR ) {
+ dwError = WSAGetLastError( );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ pDNSRecvContext->dwBytesRecvd = dwRead;
+
+ *pdwBytesRead = ( int32 ) dwRead;
+
+ return dwError;
+
+ error:
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+static int32 DNSUDPReceiveBufferContext( HANDLE hDNSHandle,
+ HANDLE hDNSRecvBuffer, int32 * pdwBytesRead )
+{
+ int32 dwError = 0;
+ int32 dwRead = 0;
+ DNS_CONNECTION_CONTEXT *pDNSContext = NULL;
+ DNS_RECEIVEBUFFER_CONTEXT *pDNSRecvContext = NULL;
+
+ pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle;
+ pDNSRecvContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hDNSRecvBuffer;
+
+ dwError = DNSSelect( hDNSHandle );
+ BAIL_ON_ERROR( dwError );
+
+ dwRead = recv( pDNSContext->s,
+ ( char * ) pDNSRecvContext->pRecvBuffer, 512, 0 );
+ if ( dwRead == SOCKET_ERROR ) {
+ dwError = WSAGetLastError( );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ pDNSRecvContext->dwBytesRecvd = dwRead;
+
+ *pdwBytesRead = ( int32 ) dwRead;
+
+ error:
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSReceiveBufferContext( HANDLE hDNSHandle,
+ HANDLE hDNSRecvBuffer, int32 * pdwBytesRead )
+{
+ int32 dwError = 0;
+ DNS_CONNECTION_CONTEXT *pDNSContext = NULL;
+
+ pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle;
+
+ switch ( pDNSContext->hType ) {
+ case DNS_TCP:
+ dwError =
+ DNSTCPReceiveBufferContext( hDNSHandle,
+ hDNSRecvBuffer,
+ pdwBytesRead );
+ break;
+ case DNS_UDP:
+ dwError =
+ DNSUDPReceiveBufferContext( hDNSHandle,
+ hDNSRecvBuffer,
+ pdwBytesRead );
+ break;
+ }
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSCreateSendBuffer( HANDLE * phDNSSendBuffer )
+{
+ int32 dwError = 0;
+ DNS_SENDBUFFER_CONTEXT *pDNSContext = NULL;
+ uint8 *pSendBuffer = NULL;
+
+ dwError = DNSAllocateMemory( sizeof( DNS_SENDBUFFER_CONTEXT ),
+ ( void ** ) &pDNSContext );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( SENDBUFFER_SIZE,
+ ( void ** ) &pSendBuffer );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSContext->pSendBuffer = pSendBuffer;
+ pDNSContext->dwBufferSize = SENDBUFFER_SIZE;
+
+ /* We will offset into the buffer by 2 bytes
+ If we are doing a TCP write; we will fill in these
+ two bytes and send + 2 bytes
+ If we are doing a UDP write; we will start our send
+ +2 bytes and only send dwWritten; */
+
+ pDNSContext->dwBufferOffset += 2;
+
+ *phDNSSendBuffer = ( HANDLE ) pDNSContext;
+
+ return dwError;
+
+ error:
+
+ if ( pSendBuffer ) {
+ DNSFreeMemory( pSendBuffer );
+ }
+ if ( pDNSContext ) {
+ DNSFreeMemory( pDNSContext );
+ }
+ *phDNSSendBuffer = ( HANDLE ) NULL;
+
+ return dwError;
+}
+
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSMarshallBuffer( HANDLE hDNSSendBuffer,
+ uint8 * pDNSSendBuffer,
+ int32 dwBufferSize, int32 * pdwBytesWritten )
+{
+ int32 dwError = 0;
+ uint8 *pTemp = NULL;
+ DNS_SENDBUFFER_CONTEXT *pDNSContext = NULL;
+
+/* BugBug - we need to check for amount of space remaining in the
+SendBuffer Context - if its insufficent, we want to realloc the
+Buffer and copy the context; Right now the assumption is we have a big
+enough buffer */
+
+ pDNSContext = ( DNS_SENDBUFFER_CONTEXT * ) hDNSSendBuffer;
+
+ pTemp = pDNSContext->pSendBuffer + pDNSContext->dwBufferOffset;
+
+ memcpy( pTemp, pDNSSendBuffer, dwBufferSize );
+
+ pDNSContext->dwBytesWritten += dwBufferSize;
+ pDNSContext->dwBufferOffset += dwBufferSize;
+
+ *pdwBytesWritten = dwBufferSize;
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+static int32 DNSTCPSendBufferContext( HANDLE hDNSServer,
+ HANDLE hSendBuffer, int32 * pdwBytesSent )
+{
+ DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL;
+ int32 dwError = 0;
+ int16 wBytesWritten = 0;
+ int16 wnBytesWritten = 0;
+
+ pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer;
+
+ wBytesWritten = ( int16 ) pSendBufferContext->dwBytesWritten;
+ wnBytesWritten = htons( wBytesWritten );
+
+ memcpy( pSendBufferContext->pSendBuffer, &wnBytesWritten,
+ sizeof( int16 ) );
+
+ dwError = DNSSendTCPRequest( hDNSServer,
+ pSendBufferContext->pSendBuffer,
+ pSendBufferContext->dwBytesWritten + 2,
+ pdwBytesSent );
+ BAIL_ON_ERROR( dwError );
+
+ error:
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+static int32 DNSUDPSendBufferContext( HANDLE hDNSServer,
+ HANDLE hSendBuffer, int32 * pdwBytesSent )
+{
+ DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL;
+ int32 dwError = 0;
+
+ pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer;
+
+ /* Now remember to send 2 bytes ahead of pSendBuffer; because
+ we ignore the 2 bytes size field. */
+
+ dwError = DNSSendUDPRequest( hDNSServer,
+ pSendBufferContext->pSendBuffer + 2,
+ pSendBufferContext->dwBytesWritten,
+ pdwBytesSent );
+ BAIL_ON_ERROR( dwError );
+
+ error:
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSSendBufferContext( HANDLE hDNSServer,
+ HANDLE hSendBuffer, int32 * pdwBytesSent )
+{
+ DNS_CONNECTION_CONTEXT *pDNSContext = NULL;
+ int32 dwError = 0;
+
+ pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSServer;
+
+ switch ( pDNSContext->hType ) {
+ case DNS_TCP:
+ dwError = DNSTCPSendBufferContext( hDNSServer,
+ hSendBuffer,
+ pdwBytesSent );
+ BAIL_ON_ERROR( dwError );
+ break;
+
+ case DNS_UDP:
+ dwError = DNSUDPSendBufferContext( hDNSServer,
+ hSendBuffer,
+ pdwBytesSent );
+ BAIL_ON_ERROR( dwError );
+ break;
+ }
+ error:
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSDumpSendBufferContext( HANDLE hSendBuffer )
+{
+ DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL;
+ int32 dwError = 0;
+ int32 dwCurLine = 0;
+ int32 i = 0;
+
+ pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer;
+ printf( "\n" );
+ printf( "Buffer Size is: %d\n", pSendBufferContext->dwBytesWritten );
+ while ( i < pSendBufferContext->dwBytesWritten ) {
+ if ( ( i / 16 ) > dwCurLine ) {
+ printf( "\n" );
+ dwCurLine++;
+ }
+ if ( ( i % 8 ) == 0 ) {
+ printf( " " );
+ }
+ printf( "%.2x ", pSendBufferContext->pSendBuffer[i] );
+ i++;
+ }
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSDumpRecvBufferContext( HANDLE hRecvBuffer )
+{
+ DNS_RECEIVEBUFFER_CONTEXT *pRecvBufferContext = NULL;
+ int32 dwError = 0;
+ int32 dwCurLine = 0;
+ int32 i = 0;
+
+ pRecvBufferContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hRecvBuffer;
+
+ printf( "\n" );
+ printf( "Buffer Size is: %d\n", pRecvBufferContext->dwBytesRecvd );
+
+ while ( i < pRecvBufferContext->dwBytesRecvd ) {
+ if ( ( i / 16 ) > dwCurLine ) {
+ printf( "\n" );
+ dwCurLine++;
+ }
+ if ( ( i % 8 ) == 0 ) {
+ printf( " " );
+ }
+ printf( "%.2x ", pRecvBufferContext->pRecvBuffer[i] );
+ i++;
+ }
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSCreateReceiveBuffer( HANDLE * phDNSRecvBuffer )
+{
+ int32 dwError = 0;
+ DNS_RECEIVEBUFFER_CONTEXT *pDNSContext = NULL;
+ uint8 *pRecvBuffer = NULL;
+
+ dwError = DNSAllocateMemory( sizeof( DNS_RECEIVEBUFFER_CONTEXT ),
+ ( void ** ) &pDNSContext );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( RECVBUFFER_SIZE,
+ ( void ** ) &pRecvBuffer );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSContext->pRecvBuffer = pRecvBuffer;
+ pDNSContext->dwBufferSize = RECVBUFFER_SIZE;
+
+ *phDNSRecvBuffer = ( HANDLE ) pDNSContext;
+
+ return dwError;
+
+ error:
+
+ if ( pRecvBuffer ) {
+ DNSFreeMemory( pRecvBuffer );
+ }
+ if ( pDNSContext ) {
+ DNSFreeMemory( pDNSContext );
+ }
+ *phDNSRecvBuffer = ( HANDLE ) NULL;
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSUnmarshallBuffer( HANDLE hDNSRecvBuffer,
+ uint8 * pDNSRecvBuffer,
+ int32 dwBufferSize, int32 * pdwBytesRead )
+{
+ int32 dwError = 0;
+ uint8 *pTemp = NULL;
+ DNS_RECEIVEBUFFER_CONTEXT *pDNSContext = NULL;
+
+/* BugBug - we need to check for amount of space remaining in the
+SendBuffer Context - if its insufficent, we want to realloc the
+Buffer and copy the context; Right now the assumption is we have a big
+enough buffer */
+
+ pDNSContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hDNSRecvBuffer;
+
+ pTemp = pDNSContext->pRecvBuffer + pDNSContext->dwBytesRead;
+
+ memcpy( pDNSRecvBuffer, pTemp, dwBufferSize );
+
+ pDNSContext->dwBytesRead += dwBufferSize;
+
+ *pdwBytesRead = dwBufferSize;
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSUnmarshallDomainNameAtOffset( HANDLE hRecvBuffer,
+ int16 wOffset,
+ 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 dwCurrent = 0;
+ DNS_RECEIVEBUFFER_CONTEXT *pRecvContext = NULL;
+
+ pRecvContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hRecvBuffer;
+ dwCurrent = wOffset;
+
+ while ( 1 ) {
+
+ memcpy( &uLen, pRecvContext->pRecvBuffer + dwCurrent,
+ sizeof( char ) );
+ dwCurrent++;
+
+ if ( uLen == 0 ) {
+ break;
+ }
+
+ memset( szLabel, 0, 65 );
+ memcpy( szLabel, pRecvContext->pRecvBuffer + dwCurrent,
+ uLen );
+ dwCurrent += uLen;
+
+ 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 DNSReceiveBufferMoveBackIndex( HANDLE hRecvBuffer, int16 wOffset )
+{
+ int32 dwError = 0;
+ DNS_RECEIVEBUFFER_CONTEXT *pDNSContext = NULL;
+
+ pDNSContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hRecvBuffer;
+ pDNSContext->dwBytesRead -= wOffset;
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+void DNSFreeSendBufferContext( HANDLE hSendBuffer )
+{
+ DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL;
+
+ pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer;
+
+ if ( pSendBufferContext->pSendBuffer ) {
+ DNSFreeMemory( pSendBufferContext->pSendBuffer );
+ }
+ if ( pSendBufferContext ) {
+ DNSFreeMemory( pSendBufferContext );
+ }
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSGetSendBufferContextSize( HANDLE hSendBuffer )
+{
+ DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL;
+
+ pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer;
+
+ return ( pSendBufferContext->dwBytesWritten );
+
+}
+
+/********************************************************************
+********************************************************************/
+
+uint8 *DNSGetSendBufferContextBuffer( HANDLE hSendBuffer )
+{
+ DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL;
+
+ pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer;
+
+ return ( pSendBufferContext->pSendBuffer );
+}
+