mirror of
https://github.com/samba-team/samba.git
synced 2024-12-28 07:21:54 +03:00
0d1e4dc5b0
(This used to be commit 6a4f4ce016
)
767 lines
20 KiB
C
767 lines
20 KiB
C
/*
|
|
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, (struct sockaddr*)&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 );
|
|
}
|
|
|