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
35 #define STATE_FINISH 2
38 #define TOKEN_SEPARATOR 2
41 /*********************************************************************
42 *********************************************************************/
44 static int32
getToken( const char *pszString
, char *pszToken
, int32
* pdwToken
,
54 dwPosition
= *pdwPosition
;
55 dwState
= STATE_BEGIN
;
56 while ( dwState
!= STATE_FINISH
) {
57 c
= pszString
[dwPosition
];
59 if ( dwState
== STATE_LABEL
) {
60 dwToken
= TOKEN_LABEL
;
61 dwState
= STATE_FINISH
;
63 } else if ( dwState
== STATE_BEGIN
) {
65 dwState
= STATE_FINISH
;
68 } else if ( isalnum( c
) || c
== '-' ) {
71 dwState
= STATE_LABEL
;
73 } else if ( c
== '.' ) {
74 if ( dwState
== STATE_LABEL
) {
75 dwToken
= TOKEN_LABEL
;
76 dwState
= STATE_FINISH
;
78 } else if ( dwState
== STATE_BEGIN
) {
79 dwToken
= TOKEN_SEPARATOR
;
81 dwState
= STATE_FINISH
;
85 if ( dwState
== STATE_LABEL
) {
86 dwToken
= TOKEN_LABEL
;
87 dwState
= STATE_FINISH
;
88 } else if ( dwState
== 0 ) {
89 dwError
= ERROR_INVALID_PARAMETER
;
90 dwState
= STATE_FINISH
;
94 *pdwPosition
= dwPosition
;
99 /*********************************************************************
100 *********************************************************************/
102 static int32
DNSMakeLabel( char *szLabel
, DNS_DOMAIN_LABEL
** ppLabel
)
104 DNS_DOMAIN_LABEL
*pLabel
= NULL
;
105 char *pszLabel
= NULL
;
109 DNSAllocateMemory( sizeof( DNS_DOMAIN_LABEL
),
110 ( void * ) &pLabel
);
111 BAIL_ON_ERROR( dwError
);
113 dwError
= DNSAllocateString( szLabel
, &pszLabel
);
114 BAIL_ON_ERROR( dwError
);
116 pLabel
->pszLabel
= pszLabel
;
117 pLabel
->dwLength
= ( int32
) strlen( pszLabel
);
124 DNSFreeMemory( pLabel
);
130 /*********************************************************************
131 *********************************************************************/
133 static void DNSFreeLabel( DNS_DOMAIN_LABEL
* pLabel
)
136 DNSFreeMemory( pLabel
);
141 /*********************************************************************
142 *********************************************************************/
144 void DNSFreeLabelList(DNS_DOMAIN_LABEL
*pLabelList
)
146 DNS_DOMAIN_LABEL
*pTemp
= NULL
;
149 pLabelList
= pLabelList
->pNext
;
156 /*********************************************************************
157 *********************************************************************/
159 void DNSFreeDomainName(DNS_DOMAIN_NAME
*pDomainName
)
161 DNSFreeLabelList(pDomainName
->pLabelList
);
162 DNSFreeMemory(pDomainName
);
167 /*********************************************************************
168 *********************************************************************/
170 static int32
LabelList( const char *pszString
, int32
* pdwPosition
, DNS_DOMAIN_LABEL
** ppList
)
173 DNS_DOMAIN_LABEL
*pList
= NULL
;
174 DNS_DOMAIN_LABEL
*pLabel
= NULL
;
178 memset( szToken
, 0, 64 );
179 dwError
= getToken( pszString
, szToken
, &dwToken
, pdwPosition
);
180 BAIL_ON_ERROR( dwError
);
181 if ( dwToken
!= TOKEN_LABEL
) {
182 dwError
= ERROR_INVALID_PARAMETER
;
183 BAIL_ON_ERROR( dwError
);
186 dwError
= DNSMakeLabel( szToken
, &pLabel
);
187 BAIL_ON_ERROR( dwError
);
189 memset( szToken
, 0, 64 );
190 dwError
= getToken( pszString
, szToken
, &dwToken
, pdwPosition
);
191 BAIL_ON_ERROR( dwError
);
192 if ( dwToken
== TOKEN_EOS
) {
195 } else if ( dwToken
== TOKEN_SEPARATOR
) {
196 dwError
= LabelList( pszString
, pdwPosition
, &pList
);
197 BAIL_ON_ERROR( dwError
);
199 pLabel
->pNext
= pList
;
207 DNSFreeLabel( pLabel
);
213 /*********************************************************************
214 *********************************************************************/
216 static int32
DNSGetDomainNameOffset( uint8
* pBuffer
)
223 if ( uLen1
& 0xC0 ) {
243 /*********************************************************************
244 *********************************************************************/
246 int32
DNSGenerateIdentifier( int16
* pwIdentifier
)
250 *pwIdentifier
= random( );
255 /*********************************************************************
256 *********************************************************************/
258 int32
DNSGetDomainNameLength( DNS_DOMAIN_NAME
* pDomainName
, int32
* pdwLength
)
262 DNS_DOMAIN_LABEL
*pDomainLabel
= NULL
;
264 if ( !pDomainName
) {
265 dwError
= ERROR_INVALID_PARAMETER
;
266 BAIL_ON_ERROR( dwError
);
268 pDomainLabel
= pDomainName
->pLabelList
;
270 while ( pDomainLabel
) {
271 dwLength
+= pDomainLabel
->dwLength
;
273 pDomainLabel
= pDomainLabel
->pNext
;
276 *pdwLength
= dwLength
;
285 /*********************************************************************
286 *********************************************************************/
288 int32
DNSCopyDomainName( uint8
* pBuffer
,
289 DNS_DOMAIN_NAME
* pDomainName
, int32
* pdwCopied
)
292 DNS_DOMAIN_LABEL
*pDomainLabel
= NULL
;
296 if ( !pDomainName
) {
297 dwError
= ERROR_INVALID_PARAMETER
;
298 BAIL_ON_ERROR( dwError
);
301 pDomainLabel
= pDomainName
->pLabelList
;
302 while ( pDomainLabel
) {
303 uChar
= ( uint8
) pDomainLabel
->dwLength
;
304 memcpy( pBuffer
+ dwCopied
, &uChar
, sizeof( uint8
) );
305 dwCopied
+= sizeof( uint8
);
306 memcpy( pBuffer
+ dwCopied
, pDomainLabel
->pszLabel
,
307 pDomainLabel
->dwLength
);
308 dwCopied
+= pDomainLabel
->dwLength
;
309 pDomainLabel
= pDomainLabel
->pNext
;
312 memcpy( pBuffer
+ dwCopied
, &uChar
, sizeof( uint8
) );
313 dwCopied
+= sizeof( uint8
);
315 *pdwCopied
= dwCopied
;
323 /*********************************************************************
324 *********************************************************************/
326 int32
DNSGenerateKeyName( char **ppszKeyName
)
329 #if defined(WITH_DNS_UPDATES)
330 char *pszKeyName
= NULL
;
333 unsigned char uuid
[16];
335 memset( szTemp
, 0, 256 );
336 memset( szBuffer
, 0, 256 );
337 memset( uuid
, 0, 16 );
339 uuid_generate( uuid
);
341 uuid_unparse( uuid
, szBuffer
);
343 strcpy( szTemp
, szBuffer
);
344 dwError
= DNSAllocateString( szTemp
, &pszKeyName
);
345 BAIL_ON_ERROR( dwError
);
347 *ppszKeyName
= pszKeyName
;
358 /*********************************************************************
359 *********************************************************************/
361 int32
DNSDomainNameFromString( const char *pszDomainName
,
362 DNS_DOMAIN_NAME
** ppDomainName
)
365 int32 dwPosition
= 0;
366 DNS_DOMAIN_NAME
*pDomainName
= NULL
;
367 DNS_DOMAIN_LABEL
*pLabelList
= NULL
;
369 if ( !pszDomainName
|| !*pszDomainName
) {
370 dwError
= ERROR_INVALID_PARAMETER
;
374 dwError
= LabelList( pszDomainName
, &dwPosition
, &pLabelList
);
375 BAIL_ON_ERROR( dwError
);
378 DNSAllocateMemory( sizeof( DNS_DOMAIN_NAME
),
379 ( void * ) &pDomainName
);
380 BAIL_ON_ERROR( dwError
);
382 pDomainName
->pLabelList
= pLabelList
;
384 *ppDomainName
= pDomainName
;
391 DNSFreeLabelList( pLabelList
);
393 *ppDomainName
= NULL
;
399 /*********************************************************************
400 *********************************************************************/
402 int32
DNSAppendLabel( DNS_DOMAIN_LABEL
* pLabelList
,
403 DNS_DOMAIN_LABEL
* pLabel
,
404 DNS_DOMAIN_LABEL
** ppNewLabelList
)
406 DNS_DOMAIN_LABEL
**ppLabelList
= NULL
;
409 if ( pLabelList
== NULL
) {
410 *ppNewLabelList
= pLabel
;
414 ppLabelList
= &pLabelList
;
416 while ( ( *ppLabelList
)->pNext
) {
417 ppLabelList
= &( ( *ppLabelList
)->pNext
);
420 ( *ppLabelList
)->pNext
= pLabel
;
421 *ppNewLabelList
= pLabelList
;
425 /*********************************************************************
426 *********************************************************************/
428 int32
GetLastError( )
433 /*********************************************************************
434 *********************************************************************/
436 int32
WSAGetLastError( void )
441 /*********************************************************************
442 *********************************************************************/
444 void DNSRecordGenerateOffsets( DNS_RR_RECORD
* pDNSRecord
)
447 uint8
*pRData
= NULL
;
448 int16 wKeySize
, wnKeySize
= 0;
450 pRData
= pDNSRecord
->pRData
;
451 switch ( pDNSRecord
->RRHeader
.wType
) {
453 pDNSRecord
->Offsets
.TKey
.wAlgorithmOffset
=
455 dwOffset
+= DNSGetDomainNameOffset( pRData
);
456 pDNSRecord
->Offsets
.TKey
.wInceptionOffset
=
458 dwOffset
+= sizeof( int32
);
459 pDNSRecord
->Offsets
.TKey
.wExpirationOffset
=
461 dwOffset
+= sizeof( int32
);
462 pDNSRecord
->Offsets
.TKey
.wModeOffset
= ( int16
) dwOffset
;
463 dwOffset
+= sizeof( int16
);
464 pDNSRecord
->Offsets
.TKey
.wErrorOffset
= ( int16
) dwOffset
;
465 dwOffset
+= sizeof( int16
);
466 pDNSRecord
->Offsets
.TKey
.wKeySizeOffset
= ( int16
) dwOffset
;
467 dwOffset
+= sizeof( int16
);
468 pDNSRecord
->Offsets
.TKey
.wKeyDataOffset
= ( int16
) dwOffset
;
471 pRData
+ pDNSRecord
->Offsets
.TKey
.wKeySizeOffset
,
473 wKeySize
= ntohs( wnKeySize
);
475 dwOffset
+= wKeySize
;
476 pDNSRecord
->Offsets
.TKey
.wOtherSizeOffset
=
478 dwOffset
+= sizeof( int16
);
479 pDNSRecord
->Offsets
.TKey
.wOtherDataOffset
=
489 /*********************************************************************
490 *********************************************************************/
492 int32
MapDNSResponseCodes( int16 wResponseCode
)
494 int16 wnResponseCode
= 0;
497 wnResponseCode
= htons( wResponseCode
);
498 pByte
= ( uint8
* ) & wnResponseCode
;
501 printf( "Byte 0 - %.2x\n", pByte
[0] );
502 printf( "Byte 1 - %.2x\n", pByte
[1] );
504 /* Bit 3, 2, 1, 0 of Byte 2 represent the RCode */
506 return ( ( int32
) pByte
[1] );
509 /*********************************************************************
510 *********************************************************************/
512 int32
DNSAllocateMemory(int32 dwSize
, void * _ppMemory
)
514 void **ppMemory
= (void **)_ppMemory
;
516 void * pMemory
= NULL
;
518 pMemory
= malloc(dwSize
);
520 dwError
= ERROR_OUTOFMEMORY
;
523 memset(pMemory
,0, dwSize
);
529 /*********************************************************************
530 *********************************************************************/
532 int32
DNSReallocMemory(void * pMemory
, void * _ppNewMemory
, int32 dwSize
)
534 void **ppNewMemory
= (void **)_ppNewMemory
;
536 void * pNewMemory
= NULL
;
538 if (pMemory
== NULL
) {
539 pNewMemory
= malloc(dwSize
);
540 memset(pNewMemory
, 0, dwSize
);
542 pNewMemory
= realloc(pMemory
, dwSize
);
545 dwError
= ERROR_OUTOFMEMORY
;
548 *ppNewMemory
= pNewMemory
;
554 /*********************************************************************
555 *********************************************************************/
557 void DNSFreeMemory( void * pMemory
)
563 /*********************************************************************
564 *********************************************************************/
566 int32
DNSAllocateString(char *pszInputString
, char **ppszOutputString
)
570 char * pszOutputString
= NULL
;
572 if (!pszInputString
|| !*pszInputString
){
573 dwError
= ERROR_INVALID_PARAMETER
;
574 BAIL_ON_ERROR(dwError
);
576 dwLen
= (int32
)strlen(pszInputString
);
577 dwError
= DNSAllocateMemory(dwLen
+1, (void *)&pszOutputString
);
578 BAIL_ON_ERROR(dwError
);
580 strcpy(pszOutputString
, pszInputString
);
582 *ppszOutputString
= pszOutputString
;
586 *ppszOutputString
= pszOutputString
;
590 /*********************************************************************
591 *********************************************************************/
593 void DNSFreeString(char * pszString
)