2 * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 Change History (most recent first):
26 Revision 1.3 2004/09/16 01:58:25 cheshire
29 Revision 1.2 2004/07/13 21:24:28 rpantos
30 Fix for <rdar://problem/3701120>.
32 Revision 1.1 2004/06/18 04:07:54 rpantos
35 Revision 1.12 2004/04/09 21:03:15 bradley
36 Changed port numbers to use network byte order for consistency with other platforms.
38 Revision 1.11 2004/01/30 03:04:32 bradley
39 Updated for latest changes to mDNSWindows.
41 Revision 1.10 2003/10/31 12:18:31 bradley
42 Added display of the resolved host name. Show separate TXT record entries on separate lines.
44 Revision 1.9 2003/10/22 02:00:20 bradley
45 Fixed proxy IP setup to be in network byte order so it works on Mac and Windows.
47 Revision 1.8 2003/10/04 04:47:08 bradley
48 Changed DNSServiceRegistrationCreate to treat the port in network byte order for end-to-end consistency.
50 Revision 1.7 2003/08/20 07:06:34 bradley
51 Update to APSL 2.0. Updated change history to match other mDNSResponder files.
53 Revision 1.6 2003/08/20 06:50:55 bradley
54 Updated to latest internal version of the mDNSCore code: Re-did everything to support
55 the latest DNSServices APIs (proxies, record updates, etc.); Added support for testing the platform
56 neutral DNSServices-based emulation layer for the Mac OS X DNSServiceDiscovery API.
60 #if( defined( _MSC_VER ) )
61 #pragma warning( disable:4068 ) // Disable "unknown pragma" warning for "pragma unused".
62 #pragma warning( disable:4127 ) // Disable "conditional expression is constant" warning for debug macros.
63 #pragma warning( disable:4311 ) // Disable "type cast : pointer truncation from void *const to int".
65 // No stdint.h with Visual C++ so emulate it here.
67 typedef signed char int8_t; // C99 stdint.h not supported in VC++/VS.NET yet.
68 typedef unsigned char uint8_t; // C99 stdint.h not supported in VC++/VS.NET yet.
69 typedef signed short int16_t; // C99 stdint.h not supported in VC++/VS.NET yet.
70 typedef unsigned short uint16_t; // C99 stdint.h not supported in VC++/VS.NET yet.
71 typedef signed long int32_t; // C99 stdint.h not supported in VC++/VS.NET yet.
72 typedef unsigned long uint32_t; // C99 stdint.h not supported in VC++/VS.NET yet.
81 #include <sys/types.h>
82 #include <sys/socket.h>
83 #include <netinet/in.h>
88 #include <CoreServices/CoreServices.h>
90 #define WIN32_LEAN_AND_MEAN
96 #include "DNSServices.h"
97 #include "DNSServiceDiscovery.h"
99 //===========================================================================================================================
101 //===========================================================================================================================
103 #if( !TARGET_OS_MAC )
104 #define require_action_string( X, LABEL, ACTION, STR ) \
109 fprintf( stderr, "%s\n", ( STR ) ); \
115 #define require_string( X, LABEL, STR ) \
120 fprintf( stderr, "%s\n", ( STR ) ); \
126 #define require_noerr_string( ERR, LABEL, STR ) \
131 fprintf( stderr, "%s (%ld)\n", ( STR ), ( ERR ) ); \
137 //===========================================================================================================================
139 //===========================================================================================================================
141 int main( int argc
, char* argv
[] );
142 static void Usage( void );
143 static int ProcessArgs( int argc
, char* argv
[] );
144 static DNSStatus
ProcessPreset( int inPreset
);
147 static void SigIntHandler( int inSignalNumber
);
150 #if( defined( WINVER ) )
151 static BOOL WINAPI
ConsoleControlHandler( DWORD inControlEvent
);
154 static void BrowserCallBack( void *inContext
, DNSBrowserRef inRef
, DNSStatus inStatusCode
, const DNSBrowserEvent
*inEvent
);
155 static void ResolverCallBack( void *inContext
, DNSResolverRef inRef
, DNSStatus inStatusCode
, const DNSResolverEvent
*inEvent
);
158 RegistrationCallBack(
160 DNSRegistrationRef inRef
,
161 DNSStatus inStatusCode
,
162 const DNSRegistrationEvent
* inEvent
);
165 HostRegistrationCallBack(
167 DNSHostRegistrationRef inRef
,
168 DNSStatus inStatusCode
,
172 EmulatedBrowserCallBack(
173 DNSServiceBrowserReplyResultType inResult
,
176 const char * inDomain
,
177 DNSServiceDiscoveryReplyFlags inFlags
,
181 EmulatedDomainEnumerationCallBack(
182 DNSServiceDomainEnumerationReplyResultType inResult
,
183 const char * inDomain
,
184 DNSServiceDiscoveryReplyFlags inFlags
,
188 EmulatedResolverCallBack(
189 struct sockaddr
* inInterfaceAddr
,
190 struct sockaddr
* inAddr
,
191 const char * inTextRecord
,
192 DNSServiceDiscoveryReplyFlags inFlags
,
195 static void EmulatedRegistrationCallBack( DNSServiceRegistrationReplyErrorType inResult
, void *inContext
);
197 static char * IPv4ToString( DNSOpaque32 inIP
, char *outString
);
199 //===========================================================================================================================
201 //===========================================================================================================================
203 #if( defined( WINVER ) )
204 static volatile int gQuit
= 0;
207 static int gPrintTXTRecords
= 1;
211 typedef struct PresetData PresetData
;
219 #pragma mark == Presets ==
222 static const PresetData gPresets
[] =
224 /* 01 */ { 2, { "DNSServiceTest", "-bbd" } },
225 /* 02 */ { 4, { "DNSServiceTest", "-bs", "_airport._tcp", "local." } },
226 /* 03 */ { 4, { "DNSServiceTest", "-bs", "_xserveraid._tcp", "local." } },
227 /* 04 */ { 3, { "DNSServiceTest", "-rdb", "apple.com" } },
228 /* 05 */ { 7, { "DNSServiceTest", "-rs", "My Fake AirPort", "_airport._tcp", "local.", "1234", "My Fake Info" } },
229 /* 06 */ { 7, { "DNSServiceTest", "-rs", "My Fake Xserve RAID", "_xserveraid._tcp", "local.", "1234", "My Fake Info" } },
230 /* 07 */ { 7, { "DNSServiceTest", "-rs", "My Fake Web Server", "_http._tcp", "local.", "8080", "index.html" } },
231 /* 08 */ { 9, { "DNSServiceTest", "-rps", "www.apple.com", "17.254.0.91", "Apple Web Server", "_http._tcp", "local.", "80", "index.html" } },
234 const int gPresetsCount
= sizeof( gPresets
) / sizeof( gPresets
[ 0 ] );
240 //===========================================================================================================================
242 //===========================================================================================================================
244 int main( int argc
, char* argv
[] )
248 // Set up DNS Services and install a Console Control Handler to handle things like control-c signals.
250 err
= DNSServicesInitialize( kDNSFlagAdvertise
, 0 );
251 require_noerr_string( err
, exit
, "could not initialize DNSServiceTest" );
254 signal( SIGINT
, SigIntHandler
);
257 #if( defined( WINVER ) )
258 SetConsoleCtrlHandler( ConsoleControlHandler
, TRUE
);
261 ProcessArgs( argc
, argv
);
264 DNSServicesFinalize();
268 //===========================================================================================================================
270 //===========================================================================================================================
272 static void Usage( void )
274 fprintf( stderr
, "\n" );
275 fprintf( stderr
, "DNSServiceTest - DNS-SD Test Tool 1.0d1\n" );
276 fprintf( stderr
, "\n" );
277 fprintf( stderr
, " -bbd 'b'rowse for 'b'rowsing 'd'omains\n" );
278 fprintf( stderr
, " -brd 'b'rowse for 'r'egistration 'd'omains\n" );
279 fprintf( stderr
, " -bs <type> <domain> 'b'rowse for 's'ervices\n" );
280 fprintf( stderr
, " -lsi <name> <type> <domain> 'l'ookup 's'ervice 'i'nstance\n" );
281 fprintf( stderr
, " -rdb[d] <domain> 'r'egister 'd'omain for 'b'rowsing ['d'efault]\n" );
282 fprintf( stderr
, " -rdr[d] <domain> 'r'egister 'd'omain for 'r'egistration ['d'efault]\n" );
283 fprintf( stderr
, " -rs <name> <type> <domain> <port> <txt> 'r'egister 's'ervice\n" );
284 fprintf( stderr
, " -rps <host> <ip> <name> <type> <domain> <port> <txt> 'r'egister 'p'roxy 's'ervice\n" );
285 fprintf( stderr
, " -rnss <name> <type> <domain> 'r'egister 'n'o 's'uch 's'ervice\n" );
287 fprintf( stderr
, " -ebs <type> <domain> 'e'mulated 'b'rowse for 's'ervices\n" );
288 fprintf( stderr
, " -ebd <registration/browse> 'e'mulated 'b'rowse for 'd'omains\n" );
289 fprintf( stderr
, " -elsi <name> <type> <domain> 'e'mulated 'l'ookup 's'ervice 'i'nstance\n" );
290 fprintf( stderr
, " -ers <name> <type> <domain> <port> <txt> 'e'mulated 'r'egister 's'ervice\n" );
292 fprintf( stderr
, " -h[elp] 'h'elp\n" );
293 fprintf( stderr
, "\n" );
295 fprintf( stderr
, " -1 Preset 1 (browse for browsing domains) DNSServiceTest -bbd\n" );
296 fprintf( stderr
, " -2 Preset 2 (browse for AirPort) DNSServiceTest -bs \"_airport._tcp\" \"local.\"\n" );
297 fprintf( stderr
, " -3 Preset 3 (browse for Xserve RAID) DNSServiceTest -bs \"_xserveraid._tcp\" \"local.\"\n" );
298 fprintf( stderr
, " -4 Preset 4 (register apple.com domain) DNSServiceTest -rdb \"apple.com\"\n" );
299 fprintf( stderr
, " -5 Preset 5 (register fake AirPort) DNSServiceTest -rs \"My Fake AirPort\" \"_airport._tcp\" \"local.\" 1234 \"My Fake Info\"\n" );
300 fprintf( stderr
, " -6 Preset 6 (register fake Xserve RAID) DNSServiceTest -rs \"My Fake Xserve RAID\" \"_xserveraid._tcp\" \"local.\" 1234 \"My Fake Info\"\n" );
301 fprintf( stderr
, " -7 Preset 7 (register fake web server) DNSServiceTest -rs \"My Fake Web Server\" \"_http._tcp\" \"local.\" 8080 \"index.html\"\n" );
302 fprintf( stderr
, "\n" );
305 //===========================================================================================================================
307 //===========================================================================================================================
309 static int ProcessArgs( int argc
, char* argv
[] )
319 DNSBrowserRef browser
;
320 DNSResolverFlags resolverFlags
;
321 DNSDomainRegistrationType domainType
;
326 DNSNetworkAddress addr
;
327 dns_service_discovery_ref emulatedRef
;
329 // Parse the command line arguments (ignore first argument since it's just the program name).
331 require_action_string( argc
>= 2, exit
, err
= kDNSBadParamErr
, "no arguments specified" );
333 for( i
= 1; i
< argc
; ++i
)
335 if( strcmp( argv
[ i
], "-bbd" ) == 0 )
337 // 'b'rowse for 'b'rowsing 'd'omains
339 fprintf( stdout
, "browsing for browsing domains\n" );
341 err
= DNSBrowserCreate( 0, BrowserCallBack
, NULL
, &browser
);
342 require_noerr_string( err
, exit
, "create browser failed" );
344 err
= DNSBrowserStartDomainSearch( browser
, 0 );
345 require_noerr_string( err
, exit
, "start domain search failed" );
347 else if( strcmp( argv
[ i
], "-brd" ) == 0 )
349 // 'b'rowse for 'r'egistration 'd'omains
351 fprintf( stdout
, "browsing for registration domains\n" );
353 err
= DNSBrowserCreate( 0, BrowserCallBack
, NULL
, &browser
);
354 require_noerr_string( err
, exit
, "create browser failed" );
356 err
= DNSBrowserStartDomainSearch( browser
, kDNSBrowserFlagRegistrationDomainsOnly
);
357 require_noerr_string( err
, exit
, "start domain search failed" );
359 else if( strcmp( argv
[ i
], "-bs" ) == 0 )
361 // 'b'rowse for 's'ervices <type> <domain>
363 require_action_string( argc
> ( i
+ 2 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
367 if( ( domain
[ 0 ] == '\0' ) || ( ( domain
[ 0 ] == '.' ) && ( domain
[ 1 ] == '\0' ) ) )
371 fprintf( stdout
, "browsing for \"%s.%s\"\n", type
, domain
);
373 err
= DNSBrowserCreate( 0, BrowserCallBack
, NULL
, &browser
);
374 require_noerr_string( err
, exit
, "create browser failed" );
376 err
= DNSBrowserStartServiceSearch( browser
, kDNSBrowserFlagAutoResolve
, type
, domain
);
377 require_noerr_string( err
, exit
, "start service search failed" );
379 else if( strcmp( argv
[ i
], "-lsi" ) == 0 )
381 // 'l'ookup 's'ervice 'i'nstance <name> <type> <domain>
383 require_action_string( argc
> ( i
+ 3 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
388 if( ( domain
[ 0 ] == '\0' ) || ( ( domain
[ 0 ] == '.' ) && ( domain
[ 1 ] == '\0' ) ) )
392 fprintf( stdout
, "resolving \"%s.%s.%s\"\n", name
, type
, domain
);
394 resolverFlags
= kDNSResolverFlagOnlyIfUnique
|
395 kDNSResolverFlagAutoReleaseByName
;
396 err
= DNSResolverCreate( resolverFlags
, name
, type
, domain
, ResolverCallBack
, 0, NULL
, NULL
);
397 require_noerr_string( err
, exit
, "create resolver failed" );
399 else if( ( strcmp( argv
[ i
], "-rdb" ) == 0 ) || ( strcmp( argv
[ i
], "-rdbd" ) == 0 ) )
401 // 'r'egister 'd'omain for 'b'rowsing ['d'efault] <domain>
403 require_action_string( argc
> ( i
+ 1 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
404 if( strcmp( argv
[ i
], "-rdb" ) == 0 )
406 domainType
= kDNSDomainRegistrationTypeBrowse
;
411 domainType
= kDNSDomainRegistrationTypeBrowseDefault
;
416 if( ( domain
[ 0 ] == '\0' ) || ( ( domain
[ 0 ] == '.' ) && ( domain
[ 1 ] == '\0' ) ) )
420 fprintf( stdout
, "registering \"%s\" as %sbrowse domain\n", domain
, label
);
422 err
= DNSDomainRegistrationCreate( 0, domain
, domainType
, NULL
);
423 require_noerr_string( err
, exit
, "create domain registration failed" );
425 else if( ( strcmp( argv
[ i
], "-rdr" ) == 0 ) || ( strcmp( argv
[ i
], "-rdrd" ) == 0 ) )
427 // 'r'egister 'd'omain for 'r'egistration ['d'efault] <domain>
429 require_action_string( argc
> ( i
+ 1 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
430 if( strcmp( argv
[ i
], "-rdr" ) == 0 )
432 domainType
= kDNSDomainRegistrationTypeRegistration
;
437 domainType
= kDNSDomainRegistrationTypeRegistrationDefault
;
442 if( ( domain
[ 0 ] == '\0' ) || ( ( domain
[ 0 ] == '.' ) && ( domain
[ 1 ] == '\0' ) ) )
446 fprintf( stdout
, "registering \"%s\" as %sregistration domain\n", domain
, label
);
448 err
= DNSDomainRegistrationCreate( 0, domain
, domainType
, NULL
);
449 require_noerr_string( err
, exit
, "create domain registration failed" );
451 else if( strcmp( argv
[ i
], "-rs" ) == 0 )
453 // 'r'egister 's'ervice <name> <type> <domain> <port> <txt>
455 require_action_string( argc
> ( i
+ 5 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
459 domain
= argv
[ i
++ ];
460 port
= (uint16_t) atoi( argv
[ i
++ ] );
462 textSize
= strlen( text
);
463 if( ( domain
[ 0 ] == '\0' ) || ( ( domain
[ 0 ] == '.' ) && ( domain
[ 1 ] == '\0' ) ) )
467 fprintf( stdout
, "registering service \"%s.%s.%s\" port %d text \"%s\"\n", name
, type
, domain
, port
, text
);
469 err
= DNSRegistrationCreate( 0, name
, type
, domain
, (DNSPort
) port
, text
, (DNSCount
) textSize
, NULL
, NULL
,
470 RegistrationCallBack
, NULL
, NULL
);
471 require_noerr_string( err
, exit
, "create registration failed" );
473 else if( strcmp( argv
[ i
], "-rps" ) == 0 )
475 DNSHostRegistrationFlags hostFlags
;
477 // 'r'egister 'p'roxy 's'ervice <host> <ip> <name> <type> <domain> <port> <txt>
479 require_action_string( argc
> ( i
+ 7 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
485 domain
= argv
[ i
++ ];
486 port
= (uint16_t) atoi( argv
[ i
++ ] );
488 textSize
= strlen( text
);
489 if( ( domain
[ 0 ] == '\0' ) || ( ( domain
[ 0 ] == '.' ) && ( domain
[ 1 ] == '\0' ) ) )
494 sscanf( ip
, "%u.%u.%u.%u", &b
[ 0 ], &b
[ 1 ], &b
[ 2 ], &b
[ 3 ] );
495 addr
.addressType
= kDNSNetworkAddressTypeIPv4
;
496 addr
.u
.ipv4
.addr
.v8
[ 0 ] = (DNSUInt8
) b
[ 0 ];
497 addr
.u
.ipv4
.addr
.v8
[ 1 ] = (DNSUInt8
) b
[ 1 ];
498 addr
.u
.ipv4
.addr
.v8
[ 2 ] = (DNSUInt8
) b
[ 2 ];
499 addr
.u
.ipv4
.addr
.v8
[ 3 ] = (DNSUInt8
) b
[ 3 ];
501 fprintf( stdout
, "registering proxy service \"%s.%s.%s\" port %d text \"%s\"\n", name
, type
, domain
, port
, text
);
503 hostFlags
= kDNSHostRegistrationFlagOnlyIfNotFound
| kDNSHostRegistrationFlagAutoRenameOnConflict
;
504 err
= DNSHostRegistrationCreate( hostFlags
, host
, domain
, &addr
, NULL
,
505 HostRegistrationCallBack
, NULL
, NULL
);
506 require_noerr_string( err
, exit
, "create host registration failed" );
508 err
= DNSRegistrationCreate( 0, name
, type
, domain
, (DNSPort
) port
, text
, (DNSCount
) textSize
, host
, NULL
,
509 RegistrationCallBack
, NULL
, NULL
);
510 require_noerr_string( err
, exit
, "create registration failed" );
512 else if( strcmp( argv
[ i
], "-rnss" ) == 0 )
514 // 'r'egister 'n'o 's'uch 's'ervice <name> <type> <domain>
516 require_action_string( argc
> ( i
+ 3 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
520 domain
= argv
[ i
++ ];
521 if( ( domain
[ 0 ] == '\0' ) || ( ( domain
[ 0 ] == '.' ) && ( domain
[ 1 ] == '\0' ) ) )
525 fprintf( stdout
, "registering no-such-service \"%s.%s.%s\"\n", name
, type
, domain
);
527 err
= DNSNoSuchServiceRegistrationCreate( 0, name
, type
, domain
, NULL
, RegistrationCallBack
, NULL
, NULL
);
528 require_noerr_string( err
, exit
, "create no-such-service registration failed" );
530 else if( strcmp( argv
[ i
], "-ebs" ) == 0 )
532 // 'e'mulated 'b'rowse for 's'ervices <type> <domain>
534 require_action_string( argc
> ( i
+ 2 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
538 if( ( domain
[ 0 ] == '\0' ) || ( ( domain
[ 0 ] == '.' ) && ( domain
[ 1 ] == '\0' ) ) )
542 fprintf( stdout
, "emulated browsing for \"%s.%s\"\n", type
, domain
);
544 emulatedRef
= DNSServiceBrowserCreate( type
, domain
, EmulatedBrowserCallBack
, NULL
);
545 require_action_string( emulatedRef
, exit
, err
= kDNSUnknownErr
, "create emulated browser failed" );
547 else if( strcmp( argv
[ i
], "-ebd" ) == 0 )
549 int registrationOnly
;
551 // 'e'mulated 'b'rowse for 'd'omains <registration/browse>
553 require_action_string( argc
> ( i
+ 1 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
556 if( strcmp( type
, "registration" ) == 0 )
558 registrationOnly
= 1;
560 else if( strcmp( type
, "browse" ) == 0 )
562 registrationOnly
= 0;
566 require_action_string( 0, exit
, err
= kDNSBadParamErr
, "invalid browse type" );
568 fprintf( stdout
, "emulated browsing for %s domains\n", type
);
570 emulatedRef
= DNSServiceDomainEnumerationCreate( registrationOnly
, EmulatedDomainEnumerationCallBack
, NULL
);
571 require_action_string( emulatedRef
, exit
, err
= kDNSUnknownErr
, "create emulated domain browser failed" );
573 else if( strcmp( argv
[ i
], "-elsi" ) == 0 )
575 // 'e'mulated 'l'ookup 's'ervice 'i'nstance <name> <type> <domain>
577 require_action_string( argc
> ( i
+ 3 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
582 if( ( domain
[ 0 ] == '\0' ) || ( ( domain
[ 0 ] == '.' ) && ( domain
[ 1 ] == '\0' ) ) )
586 fprintf( stdout
, "emulated resolving \"%s.%s.%s\"\n", name
, type
, domain
);
588 emulatedRef
= DNSServiceResolverResolve( name
, type
, domain
, EmulatedResolverCallBack
, NULL
);
589 require_action_string( emulatedRef
, exit
, err
= kDNSUnknownErr
, "create emulated resolver failed" );
591 else if( strcmp( argv
[ i
], "-ers" ) == 0 )
593 // 'e'mulated 'r'egister 's'ervice <name> <type> <domain> <port> <txt>
595 require_action_string( argc
> ( i
+ 5 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
599 domain
= argv
[ i
++ ];
600 port
= (uint16_t) atoi( argv
[ i
++ ] );
602 textSize
= strlen( text
);
603 if( ( domain
[ 0 ] == '\0' ) || ( ( domain
[ 0 ] == '.' ) && ( domain
[ 1 ] == '\0' ) ) )
607 fprintf( stdout
, "registering service \"%s.%s.%s\" port %d text \"%s\"\n", name
, type
, domain
, port
, text
);
609 emulatedRef
= DNSServiceRegistrationCreate( name
, type
, domain
, htons( port
), text
,
610 EmulatedRegistrationCallBack
, NULL
);
611 require_action_string( emulatedRef
, exit
, err
= kDNSUnknownErr
, "create emulated registration failed" );
613 else if( ( argv
[ i
][ 0 ] == '-' ) && isdigit( argv
[ i
][ 1 ] ) )
617 ProcessPreset( atoi( &argv
[ i
][ 1 ] ) );
621 else if( strcmp( argv
[ i
], "-q" ) == 0 )
623 // Quiet (no text records)
625 gPrintTXTRecords
= 0;
627 else if( ( strcmp( argv
[ i
], "-help" ) == 0 ) || ( strcmp( argv
[ i
], "-h" ) == 0 ) )
637 // Unknown parameter.
639 require_action_string( 0, exit
, err
= kDNSBadParamErr
, "unknown parameter" );
644 // Run until control-C'd.
650 #if( defined( WINVER ) )
667 //===========================================================================================================================
669 //===========================================================================================================================
671 static DNSStatus
ProcessPreset( int inPreset
)
675 require_action_string( ( inPreset
> 0 ) && ( inPreset
<= gPresetsCount
), exit
, err
= kDNSBadParamErr
, "invalid preset" );
677 err
= ProcessArgs( gPresets
[ inPreset
- 1 ].argc
, (char **) gPresets
[ inPreset
- 1 ].argv
);
684 //===========================================================================================================================
686 //===========================================================================================================================
688 static void SigIntHandler( int inSignalNumber
)
690 DNS_UNUSED( inSignalNumber
);
692 signal( SIGINT
, SIG_DFL
);
693 CFRunLoopStop( CFRunLoopGetCurrent() );
697 #if( defined( WINVER ) )
698 //===========================================================================================================================
699 // ConsoleControlHandler
700 //===========================================================================================================================
702 static BOOL WINAPI
ConsoleControlHandler( DWORD inControlEvent
)
707 switch( inControlEvent
)
710 case CTRL_BREAK_EVENT
:
711 case CTRL_CLOSE_EVENT
:
712 case CTRL_LOGOFF_EVENT
:
713 case CTRL_SHUTDOWN_EVENT
:
725 //===========================================================================================================================
727 //===========================================================================================================================
729 static void BrowserCallBack( void *inContext
, DNSBrowserRef inRef
, DNSStatus inStatusCode
, const DNSBrowserEvent
*inEvent
)
734 DNS_UNUSED( inContext
);
736 DNS_UNUSED( inStatusCode
);
738 switch( inEvent
->type
)
740 case kDNSBrowserEventTypeRelease
:
743 case kDNSBrowserEventTypeAddDomain
:
744 fprintf( stdout
, "domain \"%s\" added on interface 0x%p (%s)\n",
745 inEvent
->data
.addDomain
.domain
,
746 (int) inEvent
->data
.addDomain
.interfaceID
,
747 IPv4ToString( inEvent
->data
.addDomain
.interfaceIP
.u
.ipv4
.addr
, ifIP
) );
750 case kDNSBrowserEventTypeAddDefaultDomain
:
751 fprintf( stdout
, "default domain \"%s\" added on interface 0x%p (%s)\n",
752 inEvent
->data
.addDefaultDomain
.domain
,
753 (int) inEvent
->data
.addDefaultDomain
.interfaceID
,
754 IPv4ToString( inEvent
->data
.addDefaultDomain
.interfaceIP
.u
.ipv4
.addr
, ifIP
) );
757 case kDNSBrowserEventTypeRemoveDomain
:
758 fprintf( stdout
, "domain \"%s\" removed on interface 0x%p (%s)\n",
759 inEvent
->data
.removeDomain
.domain
,
760 (int) inEvent
->data
.removeDomain
.interfaceID
,
761 IPv4ToString( inEvent
->data
.removeDomain
.interfaceIP
.u
.ipv4
.addr
, ifIP
) );
764 case kDNSBrowserEventTypeAddService
:
765 fprintf( stdout
, "service \"%s.%s%s\" added on interface 0x%p (%s)\n",
766 inEvent
->data
.addService
.name
,
767 inEvent
->data
.addService
.type
,
768 inEvent
->data
.addService
.domain
,
769 (int) inEvent
->data
.addService
.interfaceID
,
770 IPv4ToString( inEvent
->data
.addService
.interfaceIP
.u
.ipv4
.addr
, ifIP
) );
773 case kDNSBrowserEventTypeRemoveService
:
774 fprintf( stdout
, "service \"%s.%s%s\" removed on interface 0x%p (%s)\n",
775 inEvent
->data
.removeService
.name
,
776 inEvent
->data
.removeService
.type
,
777 inEvent
->data
.removeService
.domain
,
778 (int) inEvent
->data
.removeService
.interfaceID
,
779 IPv4ToString( inEvent
->data
.removeService
.interfaceIP
.u
.ipv4
.addr
, ifIP
) );
782 case kDNSBrowserEventTypeResolved
:
788 fprintf( stdout
, "resolved \"%s.%s%s\" to \"%s\" (%s:%u) on interface 0x%p (%s)%s\n",
789 inEvent
->data
.resolved
->name
,
790 inEvent
->data
.resolved
->type
,
791 inEvent
->data
.resolved
->domain
,
792 inEvent
->data
.resolved
->hostName
,
793 IPv4ToString( inEvent
->data
.resolved
->address
.u
.ipv4
.addr
, ip
),
794 ( inEvent
->data
.resolved
->address
.u
.ipv4
.port
.v8
[ 0 ] << 8 ) |
795 inEvent
->data
.resolved
->address
.u
.ipv4
.port
.v8
[ 1 ],
796 (int) inEvent
->data
.resolved
->interfaceID
,
797 IPv4ToString( inEvent
->data
.resolved
->interfaceIP
.u
.ipv4
.addr
, ifIP
),
798 ( inEvent
->data
.resolved
->textRecordRawSize
> 0 ) ? " with text:" : "" );
800 p
= (const uint8_t *) inEvent
->data
.resolved
->textRecordRaw
;
801 end
= p
+ inEvent
->data
.resolved
->textRecordRawSize
;
804 if( gPrintTXTRecords
)
811 if( ( p
+ size
) > end
)
813 fprintf( stdout
, "\n### MALFORMED TXT RECORD (length byte too big for record)\n\n" );
816 fprintf( stdout
, "%5d (%3d bytes): \"%.*s\"\n", i
, size
, size
, p
);
820 fprintf( stdout
, "\n" );
830 //===========================================================================================================================
832 //===========================================================================================================================
834 static void ResolverCallBack( void *inContext
, DNSResolverRef inRef
, DNSStatus inStatusCode
, const DNSResolverEvent
*inEvent
)
839 DNS_UNUSED( inContext
);
841 DNS_UNUSED( inStatusCode
);
843 switch( inEvent
->type
)
845 case kDNSResolverEventTypeResolved
:
851 fprintf( stdout
, "resolved \"%s.%s%s\" to \"%s\" (%s:%u) on interface 0x%p (%s)%s\n",
852 inEvent
->data
.resolved
.name
,
853 inEvent
->data
.resolved
.type
,
854 inEvent
->data
.resolved
.domain
,
855 inEvent
->data
.resolved
.hostName
,
856 IPv4ToString( inEvent
->data
.resolved
.address
.u
.ipv4
.addr
, ip
),
857 ( inEvent
->data
.resolved
.address
.u
.ipv4
.port
.v8
[ 0 ] << 8 ) |
858 inEvent
->data
.resolved
.address
.u
.ipv4
.port
.v8
[ 1 ],
859 (int) inEvent
->data
.resolved
.interfaceID
,
860 IPv4ToString( inEvent
->data
.resolved
.interfaceIP
.u
.ipv4
.addr
, ifIP
),
861 ( inEvent
->data
.resolved
.textRecordRawSize
> 0 ) ? " with text:" : "" );
863 p
= (const uint8_t *) inEvent
->data
.resolved
.textRecordRaw
;
864 end
= p
+ inEvent
->data
.resolved
.textRecordRawSize
;
867 if( gPrintTXTRecords
)
874 if( ( p
+ size
) > end
)
876 fprintf( stdout
, "\n### MALFORMED TXT RECORD (length byte too big for record)\n\n" );
879 fprintf( stdout
, "%5d (%3d bytes): \"%.*s\"\n", i
, size
, size
, p
);
883 fprintf( stdout
, "\n" );
888 case kDNSResolverEventTypeRelease
:
896 //===========================================================================================================================
897 // RegistrationCallBack
898 //===========================================================================================================================
901 RegistrationCallBack(
903 DNSRegistrationRef inRef
,
904 DNSStatus inStatusCode
,
905 const DNSRegistrationEvent
* inEvent
)
907 DNS_UNUSED( inContext
);
909 DNS_UNUSED( inStatusCode
);
911 switch( inEvent
->type
)
913 case kDNSRegistrationEventTypeRelease
:
916 case kDNSRegistrationEventTypeRegistered
:
917 fprintf( stdout
, "name registered and active\n" );
920 case kDNSRegistrationEventTypeNameCollision
:
921 fprintf( stdout
, "name in use, please choose another name\n" );
929 //===========================================================================================================================
930 // HostRegistrationCallBack
931 //===========================================================================================================================
934 HostRegistrationCallBack(
936 DNSHostRegistrationRef inRef
,
937 DNSStatus inStatusCode
,
940 DNS_UNUSED( inContext
);
942 DNS_UNUSED( inData
);
944 if( inStatusCode
== kDNSNoErr
)
946 fprintf( stdout
, "host name registered and active\n" );
948 else if( inStatusCode
== kDNSNameConflictErr
)
950 fprintf( stdout
, "host name in use, please choose another name\n" );
954 fprintf( stdout
, "unknown host registration status (%ld)\n", inStatusCode
);
958 //===========================================================================================================================
959 // EmulatedBrowserCallBack
960 //===========================================================================================================================
963 EmulatedBrowserCallBack(
964 DNSServiceBrowserReplyResultType inResult
,
967 const char * inDomain
,
968 DNSServiceDiscoveryReplyFlags inFlags
,
971 DNS_UNUSED( inFlags
);
972 DNS_UNUSED( inContext
);
974 if( inResult
== DNSServiceBrowserReplyAddInstance
)
976 fprintf( stdout
, "\"%s.%s%s\" service added emulated\n", inName
, inType
, inDomain
);
978 else if( inResult
== DNSServiceBrowserReplyRemoveInstance
)
980 fprintf( stdout
, "\"%s.%s%s\" service removed emulated\n", inName
, inType
, inDomain
);
984 fprintf( stdout
, "### unknown emulated browser callback result (%d)\n", inResult
);
988 //===========================================================================================================================
989 // EmulatedDomainEnumerationCallBack
990 //===========================================================================================================================
993 EmulatedDomainEnumerationCallBack(
994 DNSServiceDomainEnumerationReplyResultType inResult
,
995 const char * inDomain
,
996 DNSServiceDiscoveryReplyFlags inFlags
,
999 DNS_UNUSED( inFlags
);
1000 DNS_UNUSED( inContext
);
1002 if( inResult
== DNSServiceDomainEnumerationReplyAddDomain
)
1004 fprintf( stdout
, "\"%s\" domain added emulated\n", inDomain
);
1006 else if( inResult
== DNSServiceDomainEnumerationReplyAddDomainDefault
)
1008 fprintf( stdout
, "\"%s\" default domain added emulated\n", inDomain
);
1010 else if( inResult
== DNSServiceDomainEnumerationReplyRemoveDomain
)
1012 fprintf( stdout
, "\"%s\" domain removed emulated\n", inDomain
);
1016 fprintf( stdout
, "### unknown emulated domain enumeration callback result (%d)\n", inResult
);
1020 //===========================================================================================================================
1021 // EmulatedResolverCallBack
1022 //===========================================================================================================================
1025 EmulatedResolverCallBack(
1026 struct sockaddr
* inInterfaceAddr
,
1027 struct sockaddr
* inAddr
,
1028 const char * inTextRecord
,
1029 DNSServiceDiscoveryReplyFlags inFlags
,
1032 struct sockaddr_in
* ifSin4
;
1033 struct sockaddr_in
* sin4
;
1037 DNS_UNUSED( inFlags
);
1038 DNS_UNUSED( inContext
);
1040 ifSin4
= (struct sockaddr_in
*) inInterfaceAddr
;
1041 sin4
= (struct sockaddr_in
*) inAddr
;
1043 fprintf( stdout
, "service resolved to %s:%d on interface %s with text \"%s\"\n",
1044 IPv4ToString( *( (DNSOpaque32
*) &sin4
->sin_addr
.s_addr
), ip
),
1045 ntohs( sin4
->sin_port
),
1046 IPv4ToString( *( (DNSOpaque32
*) &ifSin4
->sin_addr
.s_addr
), ifIP
),
1047 inTextRecord
? inTextRecord
: "" );
1050 //===========================================================================================================================
1051 // EmulatedResolverCallBack
1052 //===========================================================================================================================
1054 static void EmulatedRegistrationCallBack( DNSServiceRegistrationReplyErrorType inResult
, void *inContext
)
1056 DNS_UNUSED( inContext
);
1058 if( inResult
== kDNSServiceDiscoveryNoError
)
1060 fprintf( stdout
, "service name registered successfully\n" );
1064 fprintf( stdout
, "service registration failed( %d)\n", inResult
);
1068 //===========================================================================================================================
1070 //===========================================================================================================================
1072 static char * IPv4ToString( DNSOpaque32 inIP
, char *outString
)
1074 sprintf( outString
, "%u.%u.%u.%u", inIP
.v8
[ 0 ], inIP
.v8
[ 1 ], inIP
.v8
[ 2 ], inIP
.v8
[ 3 ] );
1075 return( outString
);