1 /* -*- Mode: C; tab-width: 4 -*-
3 * Copyright (c) 2006-2010 Apple Inc. All rights reserved.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
22 #include "mDNSEmbeddedAPI.h"
23 #include "DebugServices.h"
26 void yyerror( const char* error );
30 typedef struct StringListElem
33 struct StringListElem * next;
37 typedef struct OptionsInfo
39 char server_address[ 256 ];
41 char source_address[ 256 ];
48 typedef struct ZoneInfo
51 char certificate_name[ 256 ];
52 char allow_clients_file[ 256 ];
53 char allow_clients[ 256 ];
58 typedef struct KeySpec
61 char algorithm[ 256 ];
63 struct KeySpec * next;
67 typedef struct ZoneSpec
71 StringListElem * allowUpdate;
72 StringListElem * allowQuery;
74 struct ZoneSpec * next;
78 static StringListElem * g_stringList = NULL;
79 static StringListElem * g_addrList = NULL;
80 static KeySpec * g_keys;
81 static ZoneSpec * g_zones;
82 static ZoneSpec g_zoneSpec;
83 static const char * g_filename;
85 #define YYPARSE_PARAM context
124 %token <string> DOTTED_DECIMAL_ADDRESS
125 %token <string> WILDCARD
126 %token <string> DOMAINNAME
127 %token <string> HOSTNAME
128 %token <string> QUOTEDSTRING
129 %token <number> NUMBER
131 %type <string> addressstatement
132 %type <string> networkaddress
138 commands command SEMICOLON
152 OPTIONS optionscontent
154 // SetupOptions( &g_optionsInfo, context );
159 OBRACE optionsstatements EBRACE
164 optionsstatements optionsstatement SEMICOLON
171 LISTEN_ON addresscontent
175 LISTEN_ON PORT NUMBER addresscontent
177 mDNSIPPort listen_port = mDNSOpaque16fromIntVal( $3 );
178 DaemonInfo* d = ( DaemonInfo* ) context;
179 d->addr.sin_port = ( listen_port.NotAnInteger) ? listen_port.NotAnInteger : UnicastDNSPort.NotAnInteger;
180 StringListElem* addr = g_addrList;
183 StringListElem* next;
184 // The first ipv4 address in {,} is used; the rest are ignored.
185 if (inet_pton( AF_INET, addr->string, &d->addr.sin_addr ) == 0) {
186 inet_pton( AF_INET, "127.0.0.1", &d->ns_addr.sin_addr );
187 LogMsg("LISTEN_ON: An invalid ipv4 address, %s, detected.", addr->string);
195 NAMESERVER ADDRESS networkaddress
199 NAMESERVER ADDRESS networkaddress PORT NUMBER
205 ( ( DaemonInfo* ) context )->private_port = mDNSOpaque16fromIntVal( $3 );
210 ( ( DaemonInfo* ) context )->llq_port = mDNSOpaque16fromIntVal( $3 );
215 KEY QUOTEDSTRING OBRACE SECRET QUOTEDSTRING SEMICOLON EBRACE
219 keySpec = ( KeySpec* ) malloc( sizeof( KeySpec ) );
223 LogMsg("ERROR: memory allocation failure");
227 strncpy( keySpec->name, $2, sizeof( keySpec->name ) );
228 strncpy( keySpec->secret, $5, sizeof( keySpec->secret ) );
230 keySpec->next = g_keys;
236 ZONE QUOTEDSTRING zonecontent
240 zoneSpec = ( ZoneSpec* ) malloc( sizeof( ZoneSpec ) );
244 LogMsg("ERROR: memory allocation failure");
248 strncpy( zoneSpec->name, $2, sizeof( zoneSpec->name ) );
249 zoneSpec->type = g_zoneSpec.type;
250 strcpy( zoneSpec->key, g_zoneSpec.key );
251 zoneSpec->allowUpdate = g_zoneSpec.allowUpdate;
252 zoneSpec->allowQuery = g_zoneSpec.allowQuery;
254 zoneSpec->next = g_zones;
258 ZONE QUOTEDSTRING IN zonecontent
262 zoneSpec = ( ZoneSpec* ) malloc( sizeof( ZoneSpec ) );
266 LogMsg("ERROR: memory allocation failure");
270 strncpy( zoneSpec->name, $2, sizeof( zoneSpec->name ) );
271 zoneSpec->type = g_zoneSpec.type;
272 strcpy( zoneSpec->key, g_zoneSpec.key );
273 zoneSpec->allowUpdate = g_zoneSpec.allowUpdate;
274 zoneSpec->allowQuery = g_zoneSpec.allowQuery;
276 zoneSpec->next = g_zones;
282 OBRACE zonestatements EBRACE
286 zonestatements zonestatement SEMICOLON
292 g_zoneSpec.type = kDNSZonePublic;
297 g_zoneSpec.type = kDNSZonePrivate;
300 ALLOWUPDATE keycontent
302 g_zoneSpec.allowUpdate = g_stringList;
306 ALLOWQUERY keycontent
308 g_zoneSpec.allowQuery = g_stringList;
314 OBRACE addressstatements EBRACE
320 addressstatements addressstatement SEMICOLON
326 DOTTED_DECIMAL_ADDRESS
328 StringListElem * elem;
330 elem = ( StringListElem* ) malloc( sizeof( StringListElem ) );
334 LogMsg("ERROR: memory allocation failure");
340 elem->next = g_addrList;
347 OBRACE keystatements EBRACE
353 keystatements keystatement SEMICOLON
361 StringListElem * elem;
363 elem = ( StringListElem* ) malloc( sizeof( StringListElem ) );
367 LogMsg("ERROR: memory allocation failure");
373 elem->next = g_stringList;
380 DOTTED_DECIMAL_ADDRESS
388 OBRACE zonestatements EBRACE SEMICOLON
412 void yyerror( const char *str )
414 fprintf( stderr,"%s:%d: error: %s\n", g_filename, yylineno, str );
432 DomainAuthInfo * key;
439 // Tear down the current zone specifiers
445 DNSZone * next = zone->next;
447 key = zone->updateKeys;
451 DomainAuthInfo * nextKey = key->next;
458 key = zone->queryKeys;
462 DomainAuthInfo * nextKey = key->next;
476 yyin = fopen( file, "r" );
477 require_action( yyin, exit, err = 0 );
479 err = yyparse( ( void* ) d );
480 require_action( !err, exit, err = 1 );
482 for ( zoneSpec = g_zones; zoneSpec; zoneSpec = zoneSpec->next )
484 StringListElem * elem;
487 zone = ( DNSZone* ) malloc( sizeof( DNSZone ) );
488 require_action( zone, exit, err = 1 );
489 memset( zone, 0, sizeof( DNSZone ) );
491 zone->next = d->zones;
494 // Fill in the domainname
496 ok = MakeDomainNameFromDNSNameString( &zone->name, zoneSpec->name );
497 require_action( ok, exit, err = 1 );
501 zone->type = zoneSpec->type;
503 // Fill in the allow-update keys
505 for ( elem = zoneSpec->allowUpdate; elem; elem = elem->next )
507 mDNSBool found = mDNSfalse;
509 for ( keySpec = g_keys; keySpec; keySpec = keySpec->next )
511 if ( strcmp( elem->string, keySpec->name ) == 0 )
513 DomainAuthInfo * authInfo = malloc( sizeof( DomainAuthInfo ) );
515 require_action( authInfo, exit, err = 1 );
516 memset( authInfo, 0, sizeof( DomainAuthInfo ) );
518 ok = MakeDomainNameFromDNSNameString( &authInfo->keyname, keySpec->name );
519 if (!ok) { free(authInfo); err = 1; goto exit; }
521 keylen = DNSDigest_ConstructHMACKeyfromBase64( authInfo, keySpec->secret );
522 if (keylen < 0) { free(authInfo); err = 1; goto exit; }
524 authInfo->next = zone->updateKeys;
525 zone->updateKeys = authInfo;
534 require_action( found, exit, err = 1 );
537 // Fill in the allow-query keys
539 for ( elem = zoneSpec->allowQuery; elem; elem = elem->next )
541 mDNSBool found = mDNSfalse;
543 for ( keySpec = g_keys; keySpec; keySpec = keySpec->next )
545 if ( strcmp( elem->string, keySpec->name ) == 0 )
547 DomainAuthInfo * authInfo = malloc( sizeof( DomainAuthInfo ) );
549 require_action( authInfo, exit, err = 1 );
550 memset( authInfo, 0, sizeof( DomainAuthInfo ) );
552 ok = MakeDomainNameFromDNSNameString( &authInfo->keyname, keySpec->name );
553 if (!ok) { free(authInfo); err = 1; goto exit; }
555 keylen = DNSDigest_ConstructHMACKeyfromBase64( authInfo, keySpec->secret );
556 if (keylen < 0) { free(authInfo); err = 1; goto exit; }
558 authInfo->next = zone->queryKeys;
559 zone->queryKeys = authInfo;
568 require_action( found, exit, err = 1 );
585 DaemonInfo * d = ( DaemonInfo* ) context;
587 if ( strlen( info->source_address ) )
589 inet_pton( AF_INET, info->source_address, &d->addr.sin_addr );
592 if ( info->source_port )
594 d->addr.sin_port = htons( ( mDNSu16 ) info->source_port );
597 if ( strlen( info->server_address ) )
599 inet_pton( AF_INET, info->server_address, &d->ns_addr.sin_addr );
602 if ( info->server_port )
604 d->ns_addr.sin_port = htons( ( mDNSu16 ) info->server_port );
607 if ( info->private_port )
609 d->private_port = mDNSOpaque16fromIntVal( info->private_port );
612 if ( info->llq_port )
614 d->llq_port = mDNSOpaque16fromIntVal( info->llq_port );