2 Linux DNS client library implementation
4 Copyright (C) 2006 Krishna Ganugapati <krishnag@centeris.com>
5 Copyright (C) 2006 Gerald Carter <jerry@samba.org>
7 ** NOTE! The following LGPL license applies to the libaddns
8 ** library. This does NOT imply that all of Samba is released
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of the GNU Lesser General Public
13 License as published by the Free Software Foundation; either
14 version 2.1 of the License, or (at your option) any later version.
16 This library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 Lesser General Public License for more details.
21 You should have received a copy of the GNU Lesser General Public
22 License along with this library; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
29 /*********************************************************************
30 *********************************************************************/
32 static int32
DNSStdAllocateResponse( DNS_RESPONSE
** ppDNSResponse
)
35 DNS_RESPONSE
*pDNSResponse
= NULL
;
38 DNSAllocateMemory( sizeof( DNS_RESPONSE
),
39 ( void * ) &pDNSResponse
);
40 BAIL_ON_ERROR( dwError
);
42 *ppDNSResponse
= pDNSResponse
;
48 *ppDNSResponse
= NULL
;
53 /*********************************************************************
54 *********************************************************************/
56 static int32
DNSStdUnmarshallQuestionSection( HANDLE hReceiveBuffer
,
59 **pppDNSQuestionRecords
)
64 DNS_QUESTION_RECORD
*pDNSQuestionRecord
= NULL
;
65 DNS_QUESTION_RECORD
**ppDNSQuestionRecords
= NULL
;
66 int16 wnQueryClass
= 0;
67 int16 wnQueryType
= 0;
71 DNSAllocateMemory( wQuestions
*
72 sizeof( DNS_QUESTION_RECORD
* ),
73 ( void * ) &ppDNSQuestionRecords
);
74 BAIL_ON_ERROR( dwError
);
76 for ( i
= 0; i
< wQuestions
; i
++ ) {
79 DNSAllocateMemory( sizeof( DNS_QUESTION_RECORD
),
80 ( void * ) &pDNSQuestionRecord
);
81 BAIL_ON_ERROR( dwError
);
84 DNSUnmarshallDomainName( hReceiveBuffer
,
87 BAIL_ON_ERROR( dwError
);
90 DNSUnmarshallBuffer( hReceiveBuffer
,
91 ( uint8
* ) & wnQueryType
,
92 ( int32
) sizeof( int16
),
94 BAIL_ON_ERROR( dwError
);
95 pDNSQuestionRecord
->wQueryType
= ntohs( wnQueryType
);
98 DNSUnmarshallBuffer( hReceiveBuffer
,
99 ( uint8
* ) & wnQueryClass
,
100 ( int32
) sizeof( int16
),
102 BAIL_ON_ERROR( dwError
);
103 pDNSQuestionRecord
->wQueryClass
= ntohs( wnQueryClass
);
105 *( ppDNSQuestionRecords
+ i
) = pDNSQuestionRecord
;
108 *pppDNSQuestionRecords
= ppDNSQuestionRecords
;
116 /*********************************************************************
117 *********************************************************************/
119 static int32
DNSStdUnmarshallAnswerSection( HANDLE hReceiveBuffer
,
121 DNS_RR_RECORD
* **pppDNSAnswerRRRecords
)
125 DNS_RR_RECORD
*pDNSRRRecord
= NULL
;
126 DNS_RR_RECORD
**ppDNSAnswerRRRecords
= NULL
;
127 DNS_RR_HEADER RRHeader
= { 0 };
128 DNS_RR_HEADER
*pRRHeader
= &RRHeader
;
129 uint8
*pRData
= NULL
;
132 dwError
= DNSAllocateMemory( wAnswers
* sizeof( DNS_RR_RECORD
* ),
133 ( void * ) &ppDNSAnswerRRRecords
);
134 BAIL_ON_ERROR( dwError
);
136 for ( i
= 0; i
< wAnswers
; i
++ ) {
138 memset( pRRHeader
, 0, sizeof( DNS_RR_HEADER
) );
139 dwError
= DNSUnmarshallRRHeader( hReceiveBuffer
, pRRHeader
);
140 BAIL_ON_ERROR( dwError
);
144 DNSUnmarshallRData( hReceiveBuffer
,
145 pRRHeader
->wRDataSize
, &pRData
,
147 BAIL_ON_ERROR( dwError
);
150 DNSAllocateMemory( sizeof( DNS_RR_RECORD
),
151 ( void * ) &pDNSRRRecord
);
152 BAIL_ON_ERROR( dwError
);
154 memcpy( &pDNSRRRecord
->RRHeader
, pRRHeader
,
155 sizeof( DNS_RR_HEADER
) );
156 pDNSRRRecord
->pRData
= pRData
;
158 *( ppDNSAnswerRRRecords
+ i
) = pDNSRRRecord
;
161 *pppDNSAnswerRRRecords
= ppDNSAnswerRRRecords
;
171 /*********************************************************************
172 *********************************************************************/
174 static int32
DNSStdUnmarshallAuthoritySection( HANDLE hReceiveBuffer
,
176 DNS_RR_RECORD
* **pppDNSAuthorityRRRecords
)
180 DNS_RR_RECORD
*pDNSRRRecord
= NULL
;
181 DNS_RR_RECORD
**ppDNSAuthorityRRRecords
= NULL
;
182 DNS_RR_HEADER RRHeader
= { 0 };
183 DNS_RR_HEADER
*pRRHeader
= &RRHeader
;
184 uint8
*pRData
= NULL
;
187 dwError
= DNSAllocateMemory( wAuthoritys
* sizeof( DNS_RR_RECORD
* ),
188 ( void * ) &ppDNSAuthorityRRRecords
);
189 BAIL_ON_ERROR( dwError
);
191 for ( i
= 0; i
< wAuthoritys
; i
++ ) {
193 memset( pRRHeader
, 0, sizeof( DNS_RR_HEADER
) );
194 dwError
= DNSUnmarshallRRHeader( hReceiveBuffer
, pRRHeader
);
195 BAIL_ON_ERROR( dwError
);
198 DNSUnmarshallRData( hReceiveBuffer
,
199 pRRHeader
->wRDataSize
, &pRData
,
201 BAIL_ON_ERROR( dwError
);
204 DNSAllocateMemory( sizeof( DNS_RR_RECORD
),
205 ( void * ) &pDNSRRRecord
);
206 BAIL_ON_ERROR( dwError
);
208 memcpy( &pDNSRRRecord
->RRHeader
, pRRHeader
,
209 sizeof( DNS_RR_HEADER
) );
210 pDNSRRRecord
->pRData
= pRData
;
212 *( ppDNSAuthorityRRRecords
+ i
) = pDNSRRRecord
;
215 *pppDNSAuthorityRRRecords
= ppDNSAuthorityRRRecords
;
225 /*********************************************************************
226 *********************************************************************/
228 static int32
DNSStdUnmarshallAdditionalSection( HANDLE hReceiveBuffer
,
231 **pppDNSAdditionalsRRRecords
)
235 DNS_RR_RECORD
*pDNSRRRecord
= NULL
;
236 DNS_RR_RECORD
**ppDNSAdditionalRRRecords
= NULL
;
237 DNS_RR_HEADER RRHeader
= { 0 };
238 DNS_RR_HEADER
*pRRHeader
= &RRHeader
;
239 uint8
*pRData
= NULL
;
242 dwError
= DNSAllocateMemory( wAdditionals
* sizeof( DNS_RR_RECORD
* ),
243 ( void * ) &ppDNSAdditionalRRRecords
);
244 BAIL_ON_ERROR( dwError
);
246 for ( i
= 0; i
< wAdditionals
; i
++ ) {
248 memset( pRRHeader
, 0, sizeof( DNS_RR_HEADER
) );
249 dwError
= DNSUnmarshallRRHeader( hReceiveBuffer
, pRRHeader
);
250 BAIL_ON_ERROR( dwError
);
253 DNSUnmarshallRData( hReceiveBuffer
,
254 pRRHeader
->wRDataSize
, &pRData
,
256 BAIL_ON_ERROR( dwError
);
259 DNSAllocateMemory( sizeof( DNS_RR_RECORD
),
260 ( void * ) &pDNSRRRecord
);
261 BAIL_ON_ERROR( dwError
);
263 memcpy( &pDNSRRRecord
->RRHeader
, pRRHeader
,
264 sizeof( DNS_RR_HEADER
) );
265 pDNSRRRecord
->pRData
= pRData
;
268 *( ppDNSAdditionalRRRecords
+ i
) = pDNSRRRecord
;
276 /*********************************************************************
277 *********************************************************************/
279 int32
DNSStdReceiveStdResponse( HANDLE hDNSHandle
, DNS_RESPONSE
** ppDNSResponse
)
281 DNS_RESPONSE
*pDNSResponse
= NULL
;
283 int16 wnIdentification
, wIdentification
= 0;
284 int16 wnParameter
, wParameter
= 0;
285 int16 wnQuestions
, wQuestions
= 0;
286 int16 wnAnswers
, wAnswers
= 0;
287 int16 wnAdditionals
, wAdditionals
= 0;
288 int16 wnAuthoritys
, wAuthoritys
= 0;
290 DNS_RR_RECORD
**ppDNSAnswerRecords
= NULL
;
291 DNS_RR_RECORD
**ppDNSAdditionalRecords
= NULL
;
292 DNS_RR_RECORD
**ppDNSAuthorityRecords
= NULL
;
293 DNS_QUESTION_RECORD
**ppDNSQuestionRecords
= NULL
;
294 HANDLE hRecvBuffer
= ( HANDLE
) NULL
;
296 dwError
= DNSCreateReceiveBuffer( &hRecvBuffer
);
297 BAIL_ON_ERROR( dwError
);
299 dwError
= DNSReceiveBufferContext( hDNSHandle
, hRecvBuffer
, &dwRead
);
300 BAIL_ON_ERROR( dwError
);
303 dwError
= DNSDumpRecvBufferContext( hRecvBuffer
);
304 BAIL_ON_ERROR( dwError
);
308 DNSUnmarshallBuffer( hRecvBuffer
,
309 ( uint8
* ) & wnIdentification
,
310 sizeof( int16
), &dwRead
);
311 BAIL_ON_ERROR( dwError
);
312 wIdentification
= ntohs( wnIdentification
);
315 DNSUnmarshallBuffer( hRecvBuffer
, ( uint8
* ) & wnParameter
,
316 sizeof( int16
), &dwRead
);
317 BAIL_ON_ERROR( dwError
);
318 wParameter
= ntohs( wnParameter
);
322 DNSUnmarshallBuffer( hRecvBuffer
, ( uint8
* ) & wnQuestions
,
323 sizeof( int16
), &dwRead
);
324 BAIL_ON_ERROR( dwError
);
325 wQuestions
= ntohs( wnQuestions
);
329 DNSUnmarshallBuffer( hRecvBuffer
, ( uint8
* ) & wnAnswers
,
330 sizeof( int16
), &dwRead
);
331 BAIL_ON_ERROR( dwError
);
332 wAnswers
= ntohs( wnAnswers
);
336 DNSUnmarshallBuffer( hRecvBuffer
, ( uint8
* ) & wnAuthoritys
,
337 sizeof( int16
), &dwRead
);
338 BAIL_ON_ERROR( dwError
);
339 wAuthoritys
= ntohs( wnAuthoritys
);
342 DNSUnmarshallBuffer( hRecvBuffer
, ( uint8
* ) & wnAdditionals
,
343 sizeof( int16
), &dwRead
);
344 BAIL_ON_ERROR( dwError
);
345 wAdditionals
= ntohs( wnAdditionals
);
350 DNSStdUnmarshallQuestionSection( hRecvBuffer
,
352 &ppDNSQuestionRecords
);
353 BAIL_ON_ERROR( dwError
);
358 DNSStdUnmarshallAnswerSection( hRecvBuffer
, wAnswers
,
359 &ppDNSAnswerRecords
);
360 BAIL_ON_ERROR( dwError
);
365 DNSStdUnmarshallAuthoritySection( hRecvBuffer
,
367 &ppDNSAuthorityRecords
);
368 BAIL_ON_ERROR( dwError
);
371 if ( wAdditionals
) {
373 DNSStdUnmarshallAdditionalSection( hRecvBuffer
,
375 &ppDNSAdditionalRecords
);
376 BAIL_ON_ERROR( dwError
);
379 dwError
= DNSStdAllocateResponse( &pDNSResponse
);
380 BAIL_ON_ERROR( dwError
);
382 pDNSResponse
->wIdentification
= wIdentification
;
383 pDNSResponse
->wParameter
= wParameter
;
384 pDNSResponse
->wQuestions
= wQuestions
;
385 pDNSResponse
->wAnswers
= wAnswers
;
386 pDNSResponse
->wAuthoritys
= wAuthoritys
;
387 pDNSResponse
->wAdditionals
= wAdditionals
;
389 pDNSResponse
->ppQuestionRRSet
= ppDNSQuestionRecords
;
390 pDNSResponse
->ppAnswerRRSet
= ppDNSAnswerRecords
;
391 pDNSResponse
->ppAuthorityRRSet
= ppDNSAuthorityRecords
;
392 pDNSResponse
->ppAdditionalRRSet
= ppDNSAdditionalRecords
;
394 *ppDNSResponse
= pDNSResponse
;
402 /*********************************************************************
403 *********************************************************************/
405 int32
DNSUnmarshallDomainName( HANDLE hRecvBuffer
, DNS_DOMAIN_NAME
** ppDomainName
)
408 DNS_DOMAIN_LABEL
*pLabel
= NULL
;
409 DNS_DOMAIN_LABEL
*pLabelList
= NULL
;
410 DNS_DOMAIN_NAME
*pDomainName
= NULL
;
411 char *pszLabel
= NULL
;
415 uint8 uLen1
, uLen2
= 0;
416 int16 wnOffset
, wOffset
= 0;
419 DNSUnmarshallBuffer( hRecvBuffer
, &uLen1
, sizeof( char ),
421 BAIL_ON_ERROR( dwError
);
422 if ( uLen1
& 0xC0 ) {
426 DNSUnmarshallBuffer( hRecvBuffer
, &uLen2
,
427 sizeof( char ), &dwRead
);
428 BAIL_ON_ERROR( dwError
);
430 memcpy( ( uint8
* ) & wnOffset
, &uLen1
, sizeof( char ) );
431 memcpy( ( uint8
* ) & wnOffset
+ 1, &uLen2
, sizeof( char ) );
432 wOffset
= ntohs( wnOffset
);
435 DNSUnmarshallDomainNameAtOffset( hRecvBuffer
, wOffset
,
437 BAIL_ON_ERROR( dwError
);
438 *ppDomainName
= pDomainName
;
444 dwError
= DNSReceiveBufferMoveBackIndex( hRecvBuffer
, 1 );
445 BAIL_ON_ERROR( dwError
);
451 DNSUnmarshallBuffer( hRecvBuffer
, &uLen
,
454 BAIL_ON_ERROR( dwError
);
459 memset( szLabel
, 0, 65 );
461 DNSUnmarshallBuffer( hRecvBuffer
,
465 dwError
= DNSAllocateString( szLabel
, &pszLabel
);
466 BAIL_ON_ERROR( dwError
);
469 DNSAllocateMemory( sizeof( DNS_DOMAIN_LABEL
),
470 ( void * ) &pLabel
);
471 BAIL_ON_ERROR( dwError
);
473 pLabel
->pszLabel
= pszLabel
;
475 DNSAppendLabel( pLabelList
, pLabel
,
477 BAIL_ON_ERROR( dwError
);
483 DNSAllocateMemory( sizeof( DNS_DOMAIN_NAME
),
484 ( void * ) &pDomainName
);
485 BAIL_ON_ERROR( dwError
);
486 pDomainName
->pLabelList
= pLabelList
;
488 *ppDomainName
= pDomainName
;
494 *ppDomainName
= NULL
;
498 /*********************************************************************
499 *********************************************************************/
501 int32
DNSUnmarshallRRHeader( HANDLE hRecvBuffer
, DNS_RR_HEADER
* pRRHeader
)
507 int16 wnRDataSize
= 0;
511 DNSUnmarshallDomainName( hRecvBuffer
,
512 &pRRHeader
->pDomainName
);
513 BAIL_ON_ERROR( dwError
);
517 DNSUnmarshallBuffer( hRecvBuffer
, ( uint8
* ) & wnType
,
518 sizeof( int16
), &dwRead
);
519 BAIL_ON_ERROR( dwError
);
520 pRRHeader
->wType
= ntohs( wnType
);
524 DNSUnmarshallBuffer( hRecvBuffer
, ( uint8
* ) & wnClass
,
525 sizeof( int16
), &dwRead
);
526 BAIL_ON_ERROR( dwError
);
527 pRRHeader
->wClass
= ntohs( wnClass
);
530 DNSUnmarshallBuffer( hRecvBuffer
, ( uint8
* ) & dwnTTL
,
531 sizeof( int32
), &dwRead
);
532 BAIL_ON_ERROR( dwError
);
533 pRRHeader
->dwTTL
= ntohl( dwnTTL
);
536 DNSUnmarshallBuffer( hRecvBuffer
, ( uint8
* ) & wnRDataSize
,
537 sizeof( int16
), &dwRead
);
538 BAIL_ON_ERROR( dwError
);
539 pRRHeader
->wRDataSize
= htons( wnRDataSize
);
546 /*********************************************************************
547 *********************************************************************/
549 int32
DNSUnmarshallRData( HANDLE hRecvBuffer
,
550 int32 dwSize
, uint8
** ppRData
, int32
* pdwRead
)
553 uint8
*pMemory
= NULL
;
555 dwError
= DNSAllocateMemory( dwSize
, ( void * ) &pMemory
);
556 BAIL_ON_ERROR( dwError
);
558 DNSUnmarshallBuffer( hRecvBuffer
, ( uint8
* ) pMemory
, dwSize
,
560 BAIL_ON_ERROR( dwError
);
569 DNSFreeMemory( pMemory
);
576 /*********************************************************************
577 *********************************************************************/
579 int32
DNSUpdateGetResponseCode( DNS_UPDATE_RESPONSE
* pDNSUpdateResponse
,
580 int32
* pdwResponseCode
)
585 MapDNSResponseCodes( pDNSUpdateResponse
->wParameter
);