r18019: Fix a C++ warnings: Don't use void * in libads/ for LDAPMessage anymore.
[Samba/gebeck_regimport.git] / source / libaddns / dnsutils.c
blob6621509cc591050aea67fcfe9916a9179be55ef0
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"
28 #include <ctype.h>
30 #define TRUE 1
31 #define FALSE 0
33 #define STATE_BEGIN 0
34 #define STATE_LABEL 1
35 #define STATE_FINISH 2
37 #define TOKEN_LABEL 1
38 #define TOKEN_SEPARATOR 2
39 #define TOKEN_EOS 3
41 /*********************************************************************
42 *********************************************************************/
44 static int32 getToken( const char *pszString, char *pszToken, int32 * pdwToken,
45 int32 * pdwPosition )
47 int32 dwError = 0;
48 char c = 0;
49 int32 dwToken = 0;
50 int32 i = 0;
51 int32 dwState = 0;
52 int32 dwPosition = 0;
54 dwPosition = *pdwPosition;
55 dwState = STATE_BEGIN;
56 while ( dwState != STATE_FINISH ) {
57 c = pszString[dwPosition];
58 if ( c == '\0' ) {
59 if ( dwState == STATE_LABEL ) {
60 dwToken = TOKEN_LABEL;
61 dwState = STATE_FINISH;
62 continue;
63 } else if ( dwState == STATE_BEGIN ) {
64 dwToken = TOKEN_EOS;
65 dwState = STATE_FINISH;
66 continue;
68 } else if ( isalnum( c ) || c == '-' ) {
69 pszToken[i++] = c;
70 dwPosition++;
71 dwState = STATE_LABEL;
72 continue;
73 } else if ( c == '.' ) {
74 if ( dwState == STATE_LABEL ) {
75 dwToken = TOKEN_LABEL;
76 dwState = STATE_FINISH;
77 continue;
78 } else if ( dwState == STATE_BEGIN ) {
79 dwToken = TOKEN_SEPARATOR;
80 dwPosition++;
81 dwState = STATE_FINISH;
82 continue;
84 } else {
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;
95 *pdwToken = dwToken;
96 return dwError;
99 /*********************************************************************
100 *********************************************************************/
102 static int32 DNSMakeLabel( char *szLabel, DNS_DOMAIN_LABEL ** ppLabel )
104 DNS_DOMAIN_LABEL *pLabel = NULL;
105 char *pszLabel = NULL;
106 int32 dwError = 0;
108 dwError =
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 );
118 *ppLabel = pLabel;
119 return dwError;
121 error:
123 if ( pLabel ) {
124 DNSFreeMemory( pLabel );
126 *ppLabel = NULL;
127 return dwError;
130 /*********************************************************************
131 *********************************************************************/
133 static void DNSFreeLabel( DNS_DOMAIN_LABEL * pLabel )
135 if ( pLabel ) {
136 DNSFreeMemory( pLabel );
138 return;
141 /*********************************************************************
142 *********************************************************************/
144 void DNSFreeLabelList(DNS_DOMAIN_LABEL *pLabelList)
146 DNS_DOMAIN_LABEL *pTemp = NULL;
147 while(pLabelList) {
148 pTemp = pLabelList;
149 pLabelList = pLabelList->pNext;
150 DNSFreeLabel(pTemp);
153 return;
156 /*********************************************************************
157 *********************************************************************/
159 void DNSFreeDomainName(DNS_DOMAIN_NAME *pDomainName)
161 DNSFreeLabelList(pDomainName->pLabelList);
162 DNSFreeMemory(pDomainName);
164 return;
167 /*********************************************************************
168 *********************************************************************/
170 static int32 LabelList( const char *pszString, int32 * pdwPosition, DNS_DOMAIN_LABEL ** ppList )
172 int32 dwError = 0;
173 DNS_DOMAIN_LABEL *pList = NULL;
174 DNS_DOMAIN_LABEL *pLabel = NULL;
175 int32 dwToken = 0;
176 char szToken[64];
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 ) {
193 *ppList = pLabel;
194 return dwError;
195 } else if ( dwToken == TOKEN_SEPARATOR ) {
196 dwError = LabelList( pszString, pdwPosition, &pList );
197 BAIL_ON_ERROR( dwError );
199 pLabel->pNext = pList;
200 *ppList = pLabel;
203 return dwError;
205 error:
206 if ( pLabel ) {
207 DNSFreeLabel( pLabel );
210 return dwError;
213 /*********************************************************************
214 *********************************************************************/
216 static int32 DNSGetDomainNameOffset( uint8 * pBuffer )
218 uint8 uLen = 0;
219 uint8 uLen1;
220 int32 dwOffset = 0;
222 uLen1 = *pBuffer;
223 if ( uLen1 & 0xC0 ) {
224 dwOffset += 2;
226 } else {
228 while ( 1 ) {
230 uLen = *pBuffer;
231 pBuffer++;
232 dwOffset++;
233 if ( uLen == 0 ) {
234 break;
236 dwOffset += uLen;
237 pBuffer += uLen;
240 return ( dwOffset );
243 /*********************************************************************
244 *********************************************************************/
246 int32 DNSGenerateIdentifier( int16 * pwIdentifier )
248 int32 dwError = 0;
250 *pwIdentifier = random( );
252 return dwError;
255 /*********************************************************************
256 *********************************************************************/
258 int32 DNSGetDomainNameLength( DNS_DOMAIN_NAME * pDomainName, int32 * pdwLength )
260 int32 dwError = 0;
261 int32 dwLength = 0;
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;
272 dwLength += 1;
273 pDomainLabel = pDomainLabel->pNext;
275 dwLength += 1;
276 *pdwLength = dwLength;
278 return dwError;
279 error:
281 *pdwLength = 0;
282 return dwError;
285 /*********************************************************************
286 *********************************************************************/
288 int32 DNSCopyDomainName( uint8 * pBuffer,
289 DNS_DOMAIN_NAME * pDomainName, int32 * pdwCopied )
291 int32 dwError = 0;
292 DNS_DOMAIN_LABEL *pDomainLabel = NULL;
293 uint8 uChar = 0;
294 int32 dwCopied = 0;
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;
311 uChar = 0;
312 memcpy( pBuffer + dwCopied, &uChar, sizeof( uint8 ) );
313 dwCopied += sizeof( uint8 );
315 *pdwCopied = dwCopied;
316 return dwError;
318 error:
319 *pdwCopied = 0;
320 return dwError;
323 /*********************************************************************
324 *********************************************************************/
326 int32 DNSGenerateKeyName( char **ppszKeyName )
328 int32 dwError = 0;
329 #if defined(WITH_DNS_UPDATES)
330 char *pszKeyName = NULL;
331 char szTemp[256];
332 char szBuffer[256];
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;
349 return dwError;
351 error:
352 #endif
354 *ppszKeyName = NULL;
355 return dwError;
358 /*********************************************************************
359 *********************************************************************/
361 int32 DNSDomainNameFromString( const char *pszDomainName,
362 DNS_DOMAIN_NAME ** ppDomainName )
364 int32 dwError = 0;
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;
371 return dwError;
374 dwError = LabelList( pszDomainName, &dwPosition, &pLabelList );
375 BAIL_ON_ERROR( dwError );
377 dwError =
378 DNSAllocateMemory( sizeof( DNS_DOMAIN_NAME ),
379 ( void * ) &pDomainName );
380 BAIL_ON_ERROR( dwError );
382 pDomainName->pLabelList = pLabelList;
384 *ppDomainName = pDomainName;
386 return dwError;
388 error:
390 if ( pLabelList ) {
391 DNSFreeLabelList( pLabelList );
393 *ppDomainName = NULL;
395 return dwError;
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;
407 int32 dwError = 0;
409 if ( pLabelList == NULL ) {
410 *ppNewLabelList = pLabel;
411 return dwError;
414 ppLabelList = &pLabelList;
416 while ( ( *ppLabelList )->pNext ) {
417 ppLabelList = &( ( *ppLabelList )->pNext );
420 ( *ppLabelList )->pNext = pLabel;
421 *ppNewLabelList = pLabelList;
422 return dwError;
425 /*********************************************************************
426 *********************************************************************/
428 int32 GetLastError( )
430 return ( errno );
433 /*********************************************************************
434 *********************************************************************/
436 int32 WSAGetLastError( void )
438 return ( errno );
441 /*********************************************************************
442 *********************************************************************/
444 void DNSRecordGenerateOffsets( DNS_RR_RECORD * pDNSRecord )
446 int32 dwOffset = 0;
447 uint8 *pRData = NULL;
448 int16 wKeySize, wnKeySize = 0;
450 pRData = pDNSRecord->pRData;
451 switch ( pDNSRecord->RRHeader.wType ) {
452 case QTYPE_TKEY:
453 pDNSRecord->Offsets.TKey.wAlgorithmOffset =
454 ( int16 ) dwOffset;
455 dwOffset += DNSGetDomainNameOffset( pRData );
456 pDNSRecord->Offsets.TKey.wInceptionOffset =
457 ( int16 ) dwOffset;
458 dwOffset += sizeof( int32 );
459 pDNSRecord->Offsets.TKey.wExpirationOffset =
460 ( int16 ) dwOffset;
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;
470 memcpy( &wnKeySize,
471 pRData + pDNSRecord->Offsets.TKey.wKeySizeOffset,
472 sizeof( int16 ) );
473 wKeySize = ntohs( wnKeySize );
475 dwOffset += wKeySize;
476 pDNSRecord->Offsets.TKey.wOtherSizeOffset =
477 ( int16 ) dwOffset;
478 dwOffset += sizeof( int16 );
479 pDNSRecord->Offsets.TKey.wOtherDataOffset =
480 ( int16 ) dwOffset;
481 break;
483 case QTYPE_TSIG:
484 break;
486 return;
489 /*********************************************************************
490 *********************************************************************/
492 int32 MapDNSResponseCodes( int16 wResponseCode )
494 int16 wnResponseCode = 0;
495 uint8 *pByte = NULL;
497 wnResponseCode = htons( wResponseCode );
498 pByte = ( uint8 * ) & wnResponseCode;
500 #if 0
501 printf( "Byte 0 - %.2x\n", pByte[0] );
502 printf( "Byte 1 - %.2x\n", pByte[1] );
503 #endif
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;
515 int32 dwError = 0;
516 void * pMemory = NULL;
518 pMemory = malloc(dwSize);
519 if (!pMemory){
520 dwError = ERROR_OUTOFMEMORY;
521 *ppMemory = NULL;
522 }else {
523 memset(pMemory,0, dwSize);
524 *ppMemory = pMemory;
526 return (dwError);
529 /*********************************************************************
530 *********************************************************************/
532 int32 DNSReallocMemory(void * pMemory, void * _ppNewMemory, int32 dwSize)
534 void **ppNewMemory = (void **)_ppNewMemory;
535 int32 dwError = 0;
536 void * pNewMemory = NULL;
538 if (pMemory == NULL) {
539 pNewMemory = malloc(dwSize);
540 memset(pNewMemory, 0, dwSize);
541 }else {
542 pNewMemory = realloc(pMemory, dwSize);
544 if (!pNewMemory){
545 dwError = ERROR_OUTOFMEMORY;
546 *ppNewMemory = NULL;
547 }else {
548 *ppNewMemory = pNewMemory;
551 return(dwError);
554 /*********************************************************************
555 *********************************************************************/
557 void DNSFreeMemory( void * pMemory )
559 free(pMemory);
560 return;
563 /*********************************************************************
564 *********************************************************************/
566 int32 DNSAllocateString(char *pszInputString, char **ppszOutputString)
568 int32 dwError = 0;
569 int32 dwLen = 0;
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;
584 return(dwError);
585 error:
586 *ppszOutputString = pszOutputString;
587 return(dwError);
590 /*********************************************************************
591 *********************************************************************/
593 void DNSFreeString(char * pszString)
595 return;