-/*
- * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
-
- Change History (most recent first):
-
-$Log: Tool.c,v $
-Revision 1.2 2004/07/13 21:24:28 rpantos
-Fix for <rdar://problem/3701120>.
-
-Revision 1.1 2004/06/18 04:17:43 rpantos
-Move up one level.
-
-Revision 1.3 2004/04/09 21:03:15 bradley
-Changed port numbers to use network byte order for consistency with other platforms.
-
-Revision 1.2 2004/04/08 09:43:43 bradley
-Changed callback calling conventions to __stdcall so they can be used with C# delegates.
-
-Revision 1.1 2004/01/30 02:58:57 bradley
-Test tool for the mDNSResponder Windows service.
-
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "CommonServices.h"
-#include "DebugServices.h"
-#include "DNSSD.h"
-
-//===========================================================================================================================
-// Structures
-//===========================================================================================================================
-
-#define MAX_DOMAIN_LABEL 63
-#define MAX_DOMAIN_NAME 255
-
-typedef union { unsigned char b[2]; unsigned short NotAnInteger; } Opaque16;
-
-typedef struct { u_char c[ 64]; } domainlabel;
-typedef struct { u_char c[256]; } domainname;
-
-typedef struct
- {
- uint16_t priority;
- uint16_t weight;
- uint16_t port;
- domainname target;
- } srv_rdata;
-
-//===========================================================================================================================
-// Prototypes
-//===========================================================================================================================
-
-int main( int argc, char* argv[] );
-static void Usage( void );
-static int ProcessArgs( int argc, char* argv[] );
-
-#if( defined( WINVER ) )
- static BOOL WINAPI ConsoleControlHandler( DWORD inControlEvent );
-#endif
-
-static void CALLBACK_COMPAT
- EnumerateDomainsCallBack(
- DNSServiceRef inRef,
- DNSServiceFlags inFlags,
- uint32_t inInterfaceIndex,
- DNSServiceErrorType inErrorCode,
- const char * inDomain,
- void * inContext );
-
-static void CALLBACK_COMPAT
- BrowseCallBack(
- DNSServiceRef inRef,
- DNSServiceFlags inFlags,
- uint32_t inInterfaceIndex,
- DNSServiceErrorType inErrorCode,
- const char * inName,
- const char * inType,
- const char * inDomain,
- void * inContext );
-
-static void CALLBACK_COMPAT
- ResolveCallBack(
- DNSServiceRef inRef,
- DNSServiceFlags inFlags,
- uint32_t inInterfaceIndex,
- DNSServiceErrorType inErrorCode,
- const char * inFullName,
- const char * inHostName,
- uint16_t inPort,
- uint16_t inTXTSize,
- const char * inTXT,
- void * inContext );
-
-static void CALLBACK_COMPAT
- RegisterCallBack(
- DNSServiceRef inRef,
- DNSServiceFlags inFlags,
- DNSServiceErrorType inErrorCode,
- const char * inName,
- const char * inType,
- const char * inDomain,
- void * inContext );
-
-static void CALLBACK_COMPAT
- RecordCallBack(
- DNSServiceRef inRef,
- DNSRecordRef inRecordRef,
- DNSServiceFlags inFlags,
- DNSServiceErrorType inErrorCode,
- void * inContext );
-
-static void CALLBACK_COMPAT
- QueryCallBack(
- const DNSServiceRef inRef,
- const DNSServiceFlags inFlags,
- const uint32_t inInterfaceIndex,
- const DNSServiceErrorType inErrorCode,
- const char * inName,
- const uint16_t inRRType,
- const uint16_t inRRClass,
- const uint16_t inRDataSize,
- const void * inRData,
- const uint32_t inTTL,
- void * inContext );
-
-static void PrintRData( uint16_t inRRType, size_t inRDataSize, const uint8_t *inRData );
-
-static char *ConvertDomainLabelToCString_withescape(const domainlabel *const label, char *ptr, char esc);
-static char *ConvertDomainNameToCString_withescape(const domainname *const name, char *ptr, char esc);
-
-//===========================================================================================================================
-// Globals
-//===========================================================================================================================
-
-#if( defined( WINVER ) )
- static volatile int gQuit = 0;
-#endif
-
-//===========================================================================================================================
-// main
-//===========================================================================================================================
-
-int main( int argc, char *argv[] )
-{
- OSStatus err;
-
- debug_initialize( kDebugOutputTypeMetaConsole );
- debug_set_property( kDebugPropertyTagPrintLevel, kDebugLevelTrace );
-
- SetConsoleCtrlHandler( ConsoleControlHandler, TRUE );
- err = ProcessArgs( argc, argv );
- return( (int) err );
-}
-
-//===========================================================================================================================
-// Usage
-//===========================================================================================================================
-
-static void Usage( void )
-{
- fprintf( stderr, "\n" );
- fprintf( stderr, "DNSServiceTest 1.0d1\n" );
- fprintf( stderr, "\n" );
- fprintf( stderr, " -server <IP> Set Remote Server\n" );
- fprintf( stderr, " -cv Check Version\n" );
- fprintf( stderr, " -bd Browse for Browse Domains\n" );
- fprintf( stderr, " -bs <type> <domain> Browse for Services\n" );
- fprintf( stderr, " -rsi <name> <type> <domain> Resolve Service Instance\n" );
- fprintf( stderr, " -rs <name> <type> <domain> <host> <port> <txt> Register Service\n" );
- fprintf( stderr, " -rr Register Records\n" );
- fprintf( stderr, " -qr <name> <type> <domain> <rrType> Query Record\n" );
- fprintf( stderr, " -cr <name> <type> <domain> <rrType> Reconfirm Record\n" );
- fprintf( stderr, " -cp <code> Copy Property\n" );
- fprintf( stderr, " -h[elp] Help\n" );
- fprintf( stderr, "\n" );
-}
-
-DEBUG_LOCAL DNSServiceRef gRef = NULL;
-DEBUG_LOCAL DNSRecordRef gRecordRef = NULL;
-DEBUG_LOCAL const char * gServer = NULL;
-
-//===========================================================================================================================
-// ProcessArgs
-//===========================================================================================================================
-
-static int ProcessArgs( int argc, char* argv[] )
-{
- OSStatus err;
- int i;
- const char * name;
- const char * type;
- const char * domain;
- uint16_t port;
- const char * host;
- const char * txt;
- uint16_t txtSize;
- uint8_t txtStorage[ 256 ];
- uint32_t ipv4;
- char s[ 256 ];
- DNSRecordRef records[ 10 ];
- char fullName[ kDNSServiceMaxDomainName ];
- uint16_t rrType;
-
- err = DNSServiceInitialize( kDNSServiceInitializeFlagsNoServerCheck, 0 );
- require_noerr( err, exit );
-
- // Parse the command line arguments (ignore first argument since it's just the program name).
-
- if( argc <= 1 )
- {
- Usage();
- err = 0;
- goto exit;
- }
- for( i = 1; i < argc; ++i )
- {
- if( strcmp( argv[ i ], "-server" ) == 0 )
- {
- require_action( argc > ( i + 1 ), exit, err = kParamErr );
- gServer = argv[ ++i ];
-
- printf( "Server set to \"%s\"\n", gServer );
- }
- else if( strcmp( argv[ i ], "-cv" ) == 0 )
- {
- // Check Version
-
- err = DNSServiceCheckVersion();
- printf( "CheckVersion: %ld\n", err );
- err = kNoErr;
- goto exit;
- }
- else if( strcmp( argv[ i ], "-bd" ) == 0 )
- {
- err = DNSServiceEnumerateDomains( &gRef, kDNSServiceFlagsBrowseDomains, 0,
- EnumerateDomainsCallBack, NULL );
- require_noerr( err, exit );
- }
- else if( strcmp( argv[ i ], "-bs" ) == 0 )
- {
- // Browse service <type> <domain>
-
- if( argc > ( i + 2 ) )
- {
- type = argv[ ++i ];
- domain = argv[ ++i ];
- }
- else
- {
- type = "_http._tcp";
- domain = "";
- }
- if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
- {
- domain = "local.";
- }
-
- err = DNSServiceBrowse( &gRef, 0, 0, type, domain, BrowseCallBack, NULL );
- require_noerr( err, exit );
- }
- else if( strcmp( argv[ i ], "-rsi" ) == 0 )
- {
- // Resolve Service Instance <name> <type> <domain>
-
- if( argc > ( i + 3 ) )
- {
- name = argv[ ++i ];
- type = argv[ ++i ];
- domain = argv[ ++i ];
- }
- else
- {
- name = "test service";
- type = "_http._tcp";
- domain = "";
- }
- if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
- {
- domain = "local.";
- }
-
- err = DNSServiceResolve( &gRef, 0, 0, name, type, domain, ResolveCallBack, NULL );
- require_noerr( err, exit );
- }
- else if( strcmp( argv[ i ], "-rs" ) == 0 )
- {
- // Register Service <name> <type> <domain> <host> <port> <txt>
-
- if( argc > ( i + 6 ) )
- {
- name = argv[ ++i ];
- type = argv[ ++i ];
- domain = argv[ ++i ];
- host = argv[ ++i ];
- port = (uint16_t) atoi( argv[ ++i ] );
- txt = argv[ ++i ];
- }
- else
- {
- name = "test service";
- type = "_http._tcp";
- domain = "";
- host = "";
- port = 80;
- txt = "My TXT Record";
- }
- if( *txt != '\0' )
- {
- txtStorage[ 0 ] = (uint8_t) strlen( txt );
- memcpy( &txtStorage[ 1 ], txt, txtStorage[ 0 ] );
- txtSize = (uint16_t)( 1 + txtStorage[ 0 ] );
- txt = (const char *) txtStorage;
- }
- else
- {
- txt = NULL;
- txtSize = 0;
- }
- if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
- {
- domain = "local.";
- }
-
- err = DNSServiceRegister( &gRef, 0, 0, name, type, domain, host, htons( port ), txtSize, txt,
- RegisterCallBack, NULL );
- require_noerr( err, exit );
-
- #if( TEST_SERVICE_RECORDS )
- ipv4 = 0x11223344;
- err = DNSServiceAddRecord( gRef, &gRecordRef, 0, kDNSServiceDNSType_A, kDNSServiceDNSClass_IN, &ipv4, 60 );
- require_noerr( err, exit );
-
- Sleep( 10000 );
-
- ipv4 = 0x22334455;
- err = DNSServiceUpdateRecord( gRef, gRecordRef, 0, 4, &ipv4, 60 );
- require_noerr( err, exit );
-
- Sleep( 10000 );
-
- err = DNSServiceRemoveRecord( gRef, gRecordRef, 0 );
- require_noerr( err, exit );
- gRecordRef = NULL;
-
- Sleep( 10000 );
- #endif
- }
- else if( strcmp( argv[ i ], "-rr" ) == 0 )
- {
- // Register Records
-
- err = DNSServiceCreateConnection( &gRef );
- require_noerr( err, exit );
-
- printf( "registering 10 address records...\n" );
- ipv4 = 0x11223310;
- for( i = 0; i < 10; ++i )
- {
- sprintf( s, "testhost-%d.local.", i );
- ++ipv4;
- err = DNSServiceRegisterRecord( gRef, &records[ i ], kDNSServiceFlagsUnique, 0, s,
- kDNSServiceDNSType_A, kDNSServiceDNSClass_IN, 4, &ipv4, 60, RecordCallBack, NULL );
- check_noerr( err );
- }
- Sleep( 10000 );
-
- printf( "deregistering half of the records\n" );
- for( i = 0; i < 10; ++i )
- {
- if( i % 2 )
- {
- err = DNSServiceRemoveRecord( gRef, records[ i ], 0 );
- check_noerr( err );
- records[ i ] = NULL;
- }
- }
- Sleep( 10000 );
-
- printf( "updating the remaining records\n" );
- for( i = 0; i < 10; ++i )
- {
- if( records[ i ] )
- {
- ++ipv4;
- err = DNSServiceUpdateRecord( gRef, records[ i ], 0, 4, &ipv4, 60 );
- check_noerr( err );
- }
- }
- Sleep( 10000 );
-
- printf( "deregistering all remaining records\n" );
- DNSServiceRefDeallocate( gRef );
-
- Sleep( 5000 );
- }
- else if( strcmp( argv[ i ], "-qr" ) == 0 )
- {
- // Query Record <name> <type> <domain> <rrType>
-
- if( argc > ( i + 4 ) )
- {
- name = argv[ ++i ];
- type = argv[ ++i ];
- domain = argv[ ++i ];
- rrType = (uint16_t) atoi( argv[ ++i ] );
- }
- else
- {
- name = "test";
- type = "";
- domain = "";
- rrType = 1; // Address
- }
- if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
- {
- domain = "local.";
- }
- err = DNSServiceConstructFullName( fullName, name, type, domain );
- require_noerr( err, exit );
-
- printf( "resolving fullname %s type %d\n", fullName, rrType );
- err = DNSServiceQueryRecord( &gRef, 0, 0, fullName, rrType, kDNSServiceDNSClass_IN, QueryCallBack, NULL );
- require_noerr( err, exit );
- }
- else if( strcmp( argv[ i ], "-cr" ) == 0 )
- {
- // Reconfirm Record <name> <type> <domain> <rrType>
-
- if( argc > ( i + 4 ) )
- {
- name = argv[ ++i ];
- type = argv[ ++i ];
- domain = argv[ ++i ];
- rrType = (uint16_t) atoi( argv[ ++i ] );
- }
- else
- {
- name = "test";
- type = "";
- domain = "";
- rrType = 1; // Address
- }
- if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
- {
- domain = "local.";
- }
- err = DNSServiceConstructFullName( fullName, name, type, domain );
- require_noerr( err, exit );
-
- printf( "reconfirming record fullname %s type %d\n", fullName, rrType );
- ipv4 = 0x11223310;
- DNSServiceReconfirmRecord( 0, 0, fullName, rrType, kDNSServiceDNSClass_IN, 4, &ipv4 );
- }
- else if( strcmp( argv[ i ], "-cp" ) == 0 )
- {
- DNSPropertyCode code;
- DNSPropertyData data;
-
- // Copy Property <code>
-
- if( argc > ( i + 1 ) )
- {
- name = argv[ ++i ];
- require_action( strlen( name ) == 4, exit, err = kParamErr );
-
- code = (DNSPropertyCode)( name[ 0 ] << 24 );
- code |= (DNSPropertyCode)( name[ 1 ] << 16 );
- code |= (DNSPropertyCode)( name[ 2 ] << 8 );
- code |= (DNSPropertyCode) name[ 3 ];
- }
- else
- {
- code = kDNSPropertyCodeVersion;
- name = "vers";
- }
-
- err = DNSServiceCopyProperty( code, &data );
- require_noerr( err, exit );
-
- printf( "'%s' property:\n", name );
- if( code == kDNSPropertyCodeVersion )
- {
- printf( " clientCurrentVersion: 0x%08X\n", data.u.version.clientCurrentVersion );
- printf( " clientOldestServerVersion: 0x%08X\n", data.u.version.clientOldestServerVersion );
- printf( " serverCurrentVersion: 0x%08X\n", data.u.version.serverCurrentVersion );
- printf( " serverOldestClientVersion: 0x%08X\n", data.u.version.serverOldestClientVersion );
- }
- }
- else if( ( strcmp( argv[ i ], "-help" ) == 0 ) || ( strcmp( argv[ i ], "-h" ) == 0 ) )
- {
- // Help
-
- Usage();
- err = 0;
- goto exit;
- }
- else
- {
- // Unknown parameter.
-
- dlog( kDebugLevelError, "unknown parameter (%s)\n", argv[ i ] );
- err = kParamErr;
- goto exit;
- }
- }
-
- // Run until control-C'd.
-
- while( !gQuit )
- {
- Sleep( 100 );
- }
- err = kNoErr;
-
-exit:
- DNSServiceFinalize();
- if( err )
- {
- Usage();
- }
- return( err );
-}
-
-//===========================================================================================================================
-// ConsoleControlHandler
-//===========================================================================================================================
-
-static BOOL WINAPI ConsoleControlHandler( DWORD inControlEvent )
-{
- BOOL handled;
-
- handled = 0;
- switch( inControlEvent )
- {
- case CTRL_C_EVENT:
- case CTRL_BREAK_EVENT:
- case CTRL_CLOSE_EVENT:
- case CTRL_LOGOFF_EVENT:
- case CTRL_SHUTDOWN_EVENT:
- gQuit = 1;
- handled = 1;
- break;
-
- default:
- break;
- }
- return( handled );
-}
-
-//===========================================================================================================================
-// EnumerateDomainsCallBack
-//===========================================================================================================================
-
-static void CALLBACK_COMPAT
- EnumerateDomainsCallBack(
- DNSServiceRef inRef,
- DNSServiceFlags inFlags,
- uint32_t inInterfaceIndex,
- DNSServiceErrorType inErrorCode,
- const char * inDomain,
- void * inContext )
-{
- printf( "inRef: 0x%08X\n", (uintptr_t) inRef );
- printf( "inFlags: 0x%08X\n", (int) inFlags );
- printf( "inInterfaceIndex: 0x%08X\n", (int) inInterfaceIndex );
- printf( "inErrorCode: %ld\n", inErrorCode );
- printf( "inDomain: \"%s\"\n", inDomain ? inDomain : "<null>" );
- printf( "inContext: 0x%08X\n", (uintptr_t) inContext );
- printf( "\n" );
-}
-
-//===========================================================================================================================
-// BrowseCallBack
-//===========================================================================================================================
-
-static void CALLBACK_COMPAT
- BrowseCallBack(
- DNSServiceRef inRef,
- DNSServiceFlags inFlags,
- uint32_t inInterfaceIndex,
- DNSServiceErrorType inErrorCode,
- const char * inName,
- const char * inType,
- const char * inDomain,
- void * inContext )
-{
- printf( "inRef: 0x%08X\n", (uintptr_t) inRef );
- printf( "inFlags: 0x%08X\n", (int) inFlags );
- printf( "inInterfaceIndex: 0x%08X\n", (int) inInterfaceIndex );
- printf( "inErrorCode: %ld\n", inErrorCode );
- printf( "inName: \"%s\"\n", inName ? inName : "<null>" );
- printf( "inType: \"%s\"\n", inType ? inType : "<null>" );
- printf( "inDomain: \"%s\"\n", inDomain ? inDomain : "<null>" );
- printf( "inContext: 0x%08X\n", (uintptr_t) inContext );
- printf( "\n" );
-}
-
-//===========================================================================================================================
-// ResolveCallBack
-//===========================================================================================================================
-
-static void CALLBACK_COMPAT
- ResolveCallBack(
- DNSServiceRef inRef,
- DNSServiceFlags inFlags,
- uint32_t inInterfaceIndex,
- DNSServiceErrorType inErrorCode,
- const char * inFullName,
- const char * inHostName,
- uint16_t inPort,
- uint16_t inTXTSize,
- const char * inTXT,
- void * inContext )
-{
- printf( "inRef: 0x%08X\n", (uintptr_t) inRef );
- printf( "inFlags: 0x%08X\n", (int) inFlags );
- printf( "inInterfaceIndex: 0x%08X\n", (int) inInterfaceIndex );
- printf( "inErrorCode: %ld\n", inErrorCode );
- printf( "inFullName: \"%s\"\n", inFullName ? inFullName : "<null>" );
- printf( "inHostName: \"%s\"\n", inHostName ? inHostName : "<null>" );
- printf( "inPort: %d\n", ntohs( inPort ) );
- printf( "inTXTSize: %ld\n", inTXTSize );
- printf( "inTXT: 0x%08X\n", (uintptr_t) inTXT );
- printf( "inContext: 0x%08X\n", (uintptr_t) inContext );
- printf( "\n" );
-}
-
-//===========================================================================================================================
-// RegisterCallBack
-//===========================================================================================================================
-
-static void CALLBACK_COMPAT
- RegisterCallBack(
- DNSServiceRef inRef,
- DNSServiceFlags inFlags,
- DNSServiceErrorType inErrorCode,
- const char * inName,
- const char * inType,
- const char * inDomain,
- void * inContext )
-{
- printf( "inRef: 0x%08X\n", (uintptr_t) inRef );
- printf( "inFlags: 0x%08X\n", (int) inFlags );
- printf( "inErrorCode: %ld\n", inErrorCode );
- printf( "inName: \"%s\"\n", inName ? inName : "<null>" );
- printf( "inType: \"%s\"\n", inType ? inType : "<null>" );
- printf( "inDomain: \"%s\"\n", inDomain ? inDomain : "<null>" );
- printf( "inContext: 0x%08X\n", (uintptr_t) inContext );
- printf( "\n" );
-}
-
-//===========================================================================================================================
-// RecordCallBack
-//===========================================================================================================================
-
-static void CALLBACK_COMPAT
- RecordCallBack(
- DNSServiceRef inRef,
- DNSRecordRef inRecordRef,
- DNSServiceFlags inFlags,
- DNSServiceErrorType inErrorCode,
- void * inContext )
-{
- DEBUG_UNUSED( inRef );
- DEBUG_UNUSED( inRecordRef );
- DEBUG_UNUSED( inFlags );
- DEBUG_UNUSED( inContext );
-
- if( inErrorCode == kDNSServiceErr_NoError )
- {
- printf( "RecordCallBack: no errors\n" );
- }
- else
- {
- printf( "RecordCallBack: %ld error\n", inErrorCode );
- }
-}
-
-//===========================================================================================================================
-// QueryCallBack
-//===========================================================================================================================
-
-static void CALLBACK_COMPAT
- QueryCallBack(
- const DNSServiceRef inRef,
- const DNSServiceFlags inFlags,
- const uint32_t inInterfaceIndex,
- const DNSServiceErrorType inErrorCode,
- const char * inName,
- const uint16_t inRRType,
- const uint16_t inRRClass,
- const uint16_t inRDataSize,
- const void * inRData,
- const uint32_t inTTL,
- void * inContext )
-{
- DEBUG_UNUSED( inRef );
- DEBUG_UNUSED( inRRClass );
- DEBUG_UNUSED( inTTL );
- DEBUG_UNUSED( inContext );
-
- if( inErrorCode == kDNSServiceErr_NoError )
- {
- if( inFlags & kDNSServiceFlagsAdd )
- {
- printf( "Add" );
- }
- else
- {
- printf( "Rmv" );
- }
- if( inFlags & kDNSServiceFlagsMoreComing )
- {
- printf( "+" );
- }
- else
- {
- printf( " " );
- }
- printf(" 0x%04X %d %s rdata ", inFlags, inInterfaceIndex, inName );
- PrintRData( inRRType, (size_t) inRDataSize, (const uint8_t *) inRData );
- }
- else
- {
- printf( "QueryCallback: %ld error\n", inErrorCode );
- }
-}
-
-//===========================================================================================================================
-// PrintRData
-//===========================================================================================================================
-
-static void PrintRData( uint16_t inRRType, size_t inRDataSize, const uint8_t *inRData )
-{
- size_t i;
- srv_rdata * srv;
- char s[ 1005 ];
- struct in_addr in;
-
- switch( inRRType )
- {
- case kDNSServiceDNSType_TXT:
-
- // Print all the alphanumeric and punctuation characters
-
- for( i = 0; i < inRDataSize; ++i )
- {
- if( ( inRData[ i ] >= 32 ) && ( inRData[ i ] <= 127 ) )
- {
- printf( "%c", inRData[ i ] );
- }
- }
- printf( "\n" );
- break;
-
- case kDNSServiceDNSType_SRV:
- srv = (srv_rdata *)inRData;
- ConvertDomainNameToCString_withescape(&srv->target, s, 0);
- printf("pri=%d, w=%d, port=%d, target=%s\n", srv->priority, srv->weight, srv->port, s);
- break;
-
- case kDNSServiceDNSType_A:
- check( inRDataSize == 4 );
- memcpy( &in, inRData, sizeof( in ) );
- printf( "%s\n", inet_ntoa( in ) );
- break;
-
- case kDNSServiceDNSType_PTR:
- ConvertDomainNameToCString_withescape( (domainname *) inRData, s, 0 );
- break;
-
- case kDNSServiceDNSType_AAAA:
- check( inRDataSize == 16 );
- printf( "%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X\n",
- inRData[0], inRData[1], inRData[2], inRData[3], inRData[4], inRData[5], inRData[6], inRData[7], inRData[8],
- inRData[9], inRData[10], inRData[11], inRData[12], inRData[13], inRData[14], inRData[15] );
- break;
-
- default:
- printf( "ERROR: I dont know how to print inRData of type %d\n", inRRType );
- return;
- }
-}
-
-static char *ConvertDomainLabelToCString_withescape(const domainlabel *const label, char *ptr, char esc)
- {
- const unsigned char * src = label->c; // Domain label we're reading
- const unsigned char len = *src++; // Read length of this (non-null) label
- const unsigned char *const end = src + len; // Work out where the label ends
- if (len > 63) return(NULL); // If illegal label, abort
- while (src < end) // While we have characters in the label
- {
- unsigned char c = *src++;
- if (esc)
- {
- if (c == '.') // If character is a dot,
- *ptr++ = esc; // Output escape character
- else if (c <= ' ') // If non-printing ascii,
- { // Output decimal escape sequence
- *ptr++ = esc;
- *ptr++ = (char) ('0' + (c / 100) );
- *ptr++ = (char) ('0' + (c / 10) % 10);
- c = (unsigned char)('0' + (c ) % 10);
- }
- }
- *ptr++ = (char)c; // Copy the character
- }
- *ptr = 0; // Null-terminate the string
- return(ptr); // and return
- }
-
-static char *ConvertDomainNameToCString_withescape(const domainname *const name, char *ptr, char esc)
- {
- const unsigned char *src = name->c; // Domain name we're reading
- const unsigned char *const max = name->c + MAX_DOMAIN_NAME; // Maximum that's valid
-
- if (*src == 0) *ptr++ = '.'; // Special case: For root, just write a dot
-
- while (*src) // While more characters in the domain name
- {
- if (src + 1 + *src >= max) return(NULL);
- ptr = ConvertDomainLabelToCString_withescape((const domainlabel *)src, ptr, esc);
- if (!ptr) return(NULL);
- src += 1 + *src;
- *ptr++ = '.'; // Write the dot after the label
- }
-
- *ptr++ = 0; // Null-terminate the string
- return(ptr); // and return
- }