X-Git-Url: https://git.saurik.com/apple/mdnsresponder.git/blobdiff_plain/8e92c31c9a45a66732f5bc7afbc9f5596c17e91d..7f0064bd55e3fa98568d2c359429ff8a38b23a6c:/mDNSWindows/SystemServiceTest/Tool.c diff --git a/mDNSWindows/SystemServiceTest/Tool.c b/mDNSWindows/SystemServiceTest/Tool.c new file mode 100644 index 0000000..f4d675a --- /dev/null +++ b/mDNSWindows/SystemServiceTest/Tool.c @@ -0,0 +1,851 @@ +/* + * 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 . + +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 +#include + +#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 Set Remote Server\n" ); + fprintf( stderr, " -cv Check Version\n" ); + fprintf( stderr, " -bd Browse for Browse Domains\n" ); + fprintf( stderr, " -bs Browse for Services\n" ); + fprintf( stderr, " -rsi Resolve Service Instance\n" ); + fprintf( stderr, " -rs Register Service\n" ); + fprintf( stderr, " -rr Register Records\n" ); + fprintf( stderr, " -qr Query Record\n" ); + fprintf( stderr, " -cr Reconfirm Record\n" ); + fprintf( stderr, " -cp 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 + + 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 + + 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 + + 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 + + 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 + + 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 + + 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 : "" ); + 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 : "" ); + printf( "inType: \"%s\"\n", inType ? inType : "" ); + printf( "inDomain: \"%s\"\n", inDomain ? inDomain : "" ); + 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 : "" ); + printf( "inHostName: \"%s\"\n", inHostName ? inHostName : "" ); + 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 : "" ); + printf( "inType: \"%s\"\n", inType ? inType : "" ); + printf( "inDomain: \"%s\"\n", inDomain ? inDomain : "" ); + 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 + }