r19655: Jeremy, please review:
[Samba/bb.git] / source3 / libaddns / dnsresponse.c
blob9a5ff7dee77a37f6532ec51dcd2abe8cb0df39a0
1 /*
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
9 ** under the LGPL
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
24 02110-1301 USA
27 #include "dns.h"
29 /*********************************************************************
30 *********************************************************************/
32 static int32 DNSStdAllocateResponse( DNS_RESPONSE ** ppDNSResponse )
34 int32 dwError = 0;
35 DNS_RESPONSE *pDNSResponse = NULL;
37 dwError =
38 DNSAllocateMemory( sizeof( DNS_RESPONSE ),
39 ( void * ) &pDNSResponse );
40 BAIL_ON_ERROR( dwError );
42 *ppDNSResponse = pDNSResponse;
44 return dwError;
46 error:
48 *ppDNSResponse = NULL;
50 return dwError;
53 /*********************************************************************
54 *********************************************************************/
56 static int32 DNSStdUnmarshallQuestionSection( HANDLE hReceiveBuffer,
57 int16 wQuestions,
58 DNS_QUESTION_RECORD *
59 **pppDNSQuestionRecords )
61 int32 dwError = 0;
62 int32 i = 0;
63 int32 dwRead = 0;
64 DNS_QUESTION_RECORD *pDNSQuestionRecord = NULL;
65 DNS_QUESTION_RECORD **ppDNSQuestionRecords = NULL;
66 int16 wnQueryClass = 0;
67 int16 wnQueryType = 0;
70 dwError =
71 DNSAllocateMemory( wQuestions *
72 sizeof( DNS_QUESTION_RECORD * ),
73 ( void * ) &ppDNSQuestionRecords );
74 BAIL_ON_ERROR( dwError );
76 for ( i = 0; i < wQuestions; i++ ) {
78 dwError =
79 DNSAllocateMemory( sizeof( DNS_QUESTION_RECORD ),
80 ( void * ) &pDNSQuestionRecord );
81 BAIL_ON_ERROR( dwError );
83 dwError =
84 DNSUnmarshallDomainName( hReceiveBuffer,
85 &pDNSQuestionRecord->
86 pDomainName );
87 BAIL_ON_ERROR( dwError );
89 dwError =
90 DNSUnmarshallBuffer( hReceiveBuffer,
91 ( uint8 * ) & wnQueryType,
92 ( int32 ) sizeof( int16 ),
93 &dwRead );
94 BAIL_ON_ERROR( dwError );
95 pDNSQuestionRecord->wQueryType = ntohs( wnQueryType );
97 dwError =
98 DNSUnmarshallBuffer( hReceiveBuffer,
99 ( uint8 * ) & wnQueryClass,
100 ( int32 ) sizeof( int16 ),
101 &dwRead );
102 BAIL_ON_ERROR( dwError );
103 pDNSQuestionRecord->wQueryClass = ntohs( wnQueryClass );
105 *( ppDNSQuestionRecords + i ) = pDNSQuestionRecord;
108 *pppDNSQuestionRecords = ppDNSQuestionRecords;
109 return dwError;
111 error:
113 return dwError;
116 /*********************************************************************
117 *********************************************************************/
119 static int32 DNSStdUnmarshallAnswerSection( HANDLE hReceiveBuffer,
120 int16 wAnswers,
121 DNS_RR_RECORD * **pppDNSAnswerRRRecords )
123 int32 dwError = 0;
124 int32 i = 0;
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;
130 int32 dwRead = 0;
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 );
143 dwError =
144 DNSUnmarshallRData( hReceiveBuffer,
145 pRRHeader->wRDataSize, &pRData,
146 &dwRead );
147 BAIL_ON_ERROR( dwError );
149 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;
163 return dwError;
165 error:
168 return dwError;
171 /*********************************************************************
172 *********************************************************************/
174 static int32 DNSStdUnmarshallAuthoritySection( HANDLE hReceiveBuffer,
175 int16 wAuthoritys,
176 DNS_RR_RECORD * **pppDNSAuthorityRRRecords )
178 int32 dwError = 0;
179 int32 i = 0;
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;
185 int32 dwRead = 0;
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 );
197 dwError =
198 DNSUnmarshallRData( hReceiveBuffer,
199 pRRHeader->wRDataSize, &pRData,
200 &dwRead );
201 BAIL_ON_ERROR( dwError );
203 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;
217 return dwError;
219 error:
221 return dwError;
225 /*********************************************************************
226 *********************************************************************/
228 static int32 DNSStdUnmarshallAdditionalSection( HANDLE hReceiveBuffer,
229 int16 wAdditionals,
230 DNS_RR_RECORD *
231 **pppDNSAdditionalsRRRecords )
233 int32 dwError = 0;
234 int32 i = 0;
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;
240 int32 dwRead = 0;
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 );
252 dwError =
253 DNSUnmarshallRData( hReceiveBuffer,
254 pRRHeader->wRDataSize, &pRData,
255 &dwRead );
256 BAIL_ON_ERROR( dwError );
258 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;
271 error:
273 return dwError;
276 /*********************************************************************
277 *********************************************************************/
279 int32 DNSStdReceiveStdResponse( HANDLE hDNSHandle, DNS_RESPONSE ** ppDNSResponse )
281 DNS_RESPONSE *pDNSResponse = NULL;
282 int32 dwError = 0;
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;
289 int32 dwRead = 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 );
302 #if 0
303 dwError = DNSDumpRecvBufferContext( hRecvBuffer );
304 BAIL_ON_ERROR( dwError );
305 #endif
307 dwError =
308 DNSUnmarshallBuffer( hRecvBuffer,
309 ( uint8 * ) & wnIdentification,
310 sizeof( int16 ), &dwRead );
311 BAIL_ON_ERROR( dwError );
312 wIdentification = ntohs( wnIdentification );
314 dwError =
315 DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnParameter,
316 sizeof( int16 ), &dwRead );
317 BAIL_ON_ERROR( dwError );
318 wParameter = ntohs( wnParameter );
321 dwError =
322 DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnQuestions,
323 sizeof( int16 ), &dwRead );
324 BAIL_ON_ERROR( dwError );
325 wQuestions = ntohs( wnQuestions );
328 dwError =
329 DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnAnswers,
330 sizeof( int16 ), &dwRead );
331 BAIL_ON_ERROR( dwError );
332 wAnswers = ntohs( wnAnswers );
335 dwError =
336 DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnAuthoritys,
337 sizeof( int16 ), &dwRead );
338 BAIL_ON_ERROR( dwError );
339 wAuthoritys = ntohs( wnAuthoritys );
341 dwError =
342 DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnAdditionals,
343 sizeof( int16 ), &dwRead );
344 BAIL_ON_ERROR( dwError );
345 wAdditionals = ntohs( wnAdditionals );
348 if ( wQuestions ) {
349 dwError =
350 DNSStdUnmarshallQuestionSection( hRecvBuffer,
351 wQuestions,
352 &ppDNSQuestionRecords );
353 BAIL_ON_ERROR( dwError );
356 if ( wAnswers ) {
357 dwError =
358 DNSStdUnmarshallAnswerSection( hRecvBuffer, wAnswers,
359 &ppDNSAnswerRecords );
360 BAIL_ON_ERROR( dwError );
363 if ( wAuthoritys ) {
364 dwError =
365 DNSStdUnmarshallAuthoritySection( hRecvBuffer,
366 wAuthoritys,
367 &ppDNSAuthorityRecords );
368 BAIL_ON_ERROR( dwError );
371 if ( wAdditionals ) {
372 dwError =
373 DNSStdUnmarshallAdditionalSection( hRecvBuffer,
374 wAdditionals,
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;
397 error:
399 return dwError;
402 /*********************************************************************
403 *********************************************************************/
405 int32 DNSUnmarshallDomainName( HANDLE hRecvBuffer, DNS_DOMAIN_NAME ** ppDomainName )
407 int32 dwError = 0;
408 DNS_DOMAIN_LABEL *pLabel = NULL;
409 DNS_DOMAIN_LABEL *pLabelList = NULL;
410 DNS_DOMAIN_NAME *pDomainName = NULL;
411 char *pszLabel = NULL;
412 char szLabel[65];
413 uint8 uLen = 0;
414 int32 dwRead = 0;
415 uint8 uLen1, uLen2 = 0;
416 int16 wnOffset, wOffset = 0;
418 dwError =
419 DNSUnmarshallBuffer( hRecvBuffer, &uLen1, sizeof( char ),
420 &dwRead );
421 BAIL_ON_ERROR( dwError );
422 if ( uLen1 & 0xC0 ) {
424 uLen1 |= 0x3F;
425 dwError =
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 );
434 dwError =
435 DNSUnmarshallDomainNameAtOffset( hRecvBuffer, wOffset,
436 &pDomainName );
437 BAIL_ON_ERROR( dwError );
438 *ppDomainName = pDomainName;
440 return dwError;
442 } else {
444 dwError = DNSReceiveBufferMoveBackIndex( hRecvBuffer, 1 );
445 BAIL_ON_ERROR( dwError );
447 while ( 1 ) {
450 dwError =
451 DNSUnmarshallBuffer( hRecvBuffer, &uLen,
452 sizeof( char ),
453 &dwRead );
454 BAIL_ON_ERROR( dwError );
455 if ( uLen == 0 ) {
456 break;
459 memset( szLabel, 0, 65 );
460 dwError =
461 DNSUnmarshallBuffer( hRecvBuffer,
462 ( uint8 * ) szLabel,
463 uLen, &dwRead );
465 dwError = DNSAllocateString( szLabel, &pszLabel );
466 BAIL_ON_ERROR( dwError );
468 dwError =
469 DNSAllocateMemory( sizeof( DNS_DOMAIN_LABEL ),
470 ( void * ) &pLabel );
471 BAIL_ON_ERROR( dwError );
473 pLabel->pszLabel = pszLabel;
474 dwError =
475 DNSAppendLabel( pLabelList, pLabel,
476 &pLabelList );
477 BAIL_ON_ERROR( dwError );
482 dwError =
483 DNSAllocateMemory( sizeof( DNS_DOMAIN_NAME ),
484 ( void * ) &pDomainName );
485 BAIL_ON_ERROR( dwError );
486 pDomainName->pLabelList = pLabelList;
488 *ppDomainName = pDomainName;
490 return dwError;
492 error:
494 *ppDomainName = NULL;
495 return dwError;
498 /*********************************************************************
499 *********************************************************************/
501 int32 DNSUnmarshallRRHeader( HANDLE hRecvBuffer, DNS_RR_HEADER * pRRHeader )
503 int32 dwError = 0;
504 int32 dwRead = 0;
505 int16 wnType = 0;
506 int16 wnClass = 0;
507 int16 wnRDataSize = 0;
508 int32 dwnTTL = 0;
510 dwError =
511 DNSUnmarshallDomainName( hRecvBuffer,
512 &pRRHeader->pDomainName );
513 BAIL_ON_ERROR( dwError );
516 dwError =
517 DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnType,
518 sizeof( int16 ), &dwRead );
519 BAIL_ON_ERROR( dwError );
520 pRRHeader->wType = ntohs( wnType );
523 dwError =
524 DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnClass,
525 sizeof( int16 ), &dwRead );
526 BAIL_ON_ERROR( dwError );
527 pRRHeader->wClass = ntohs( wnClass );
529 dwError =
530 DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & dwnTTL,
531 sizeof( int32 ), &dwRead );
532 BAIL_ON_ERROR( dwError );
533 pRRHeader->dwTTL = ntohl( dwnTTL );
535 dwError =
536 DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnRDataSize,
537 sizeof( int16 ), &dwRead );
538 BAIL_ON_ERROR( dwError );
539 pRRHeader->wRDataSize = htons( wnRDataSize );
541 error:
543 return dwError;
546 /*********************************************************************
547 *********************************************************************/
549 int32 DNSUnmarshallRData( HANDLE hRecvBuffer,
550 int32 dwSize, uint8 ** ppRData, int32 * pdwRead )
552 int32 dwError = 0;
553 uint8 *pMemory = NULL;
555 dwError = DNSAllocateMemory( dwSize, ( void * ) &pMemory );
556 BAIL_ON_ERROR( dwError );
557 dwError =
558 DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) pMemory, dwSize,
559 pdwRead );
560 BAIL_ON_ERROR( dwError );
562 *ppRData = pMemory;
564 return dwError;
566 error:
568 if ( pMemory ) {
569 DNSFreeMemory( pMemory );
572 *ppRData = NULL;
573 return dwError;
576 /*********************************************************************
577 *********************************************************************/
579 int32 DNSUpdateGetResponseCode( DNS_UPDATE_RESPONSE * pDNSUpdateResponse,
580 int32 * pdwResponseCode )
582 int32 dwError = 0;
584 *pdwResponseCode =
585 MapDNSResponseCodes( pDNSUpdateResponse->wParameter );
587 return dwError;