1 /* -*- Mode: C; tab-width: 4 -*-
3 * Copyright (c) 2002-2004 Apple Computer, 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.
17 Change History (most recent first):
20 Revision 1.4 2006/08/14 23:25:59 cheshire
21 Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
23 Revision 1.3 2004/09/16 01:58:25 cheshire
26 Revision 1.2 2004/07/13 21:24:28 rpantos
27 Fix for <rdar://problem/3701120>.
29 Revision 1.1 2004/06/18 04:07:54 rpantos
32 Revision 1.12 2004/04/09 21:03:15 bradley
33 Changed port numbers to use network byte order for consistency with other platforms.
35 Revision 1.11 2004/01/30 03:04:32 bradley
36 Updated for latest changes to mDNSWindows.
38 Revision 1.10 2003/10/31 12:18:31 bradley
39 Added display of the resolved host name. Show separate TXT record entries on separate lines.
41 Revision 1.9 2003/10/22 02:00:20 bradley
42 Fixed proxy IP setup to be in network byte order so it works on Mac and Windows.
44 Revision 1.8 2003/10/04 04:47:08 bradley
45 Changed DNSServiceRegistrationCreate to treat the port in network byte order for end-to-end consistency.
47 Revision 1.7 2003/08/20 07:06:34 bradley
48 Update to APSL 2.0. Updated change history to match other mDNSResponder files.
50 Revision 1.6 2003/08/20 06:50:55 bradley
51 Updated to latest internal version of the mDNSCore code: Re-did everything to support
52 the latest DNSServices APIs (proxies, record updates, etc.); Added support for testing the platform
53 neutral DNSServices-based emulation layer for the Mac OS X DNSServiceDiscovery API.
57 #if( defined( _MSC_VER ) )
58 #pragma warning( disable:4068 ) // Disable "unknown pragma" warning for "pragma unused".
59 #pragma warning( disable:4127 ) // Disable "conditional expression is constant" warning for debug macros.
60 #pragma warning( disable:4311 ) // Disable "type cast : pointer truncation from void *const to int".
62 // No stdint.h with Visual C++ so emulate it here.
64 typedef signed char int8_t; // C99 stdint.h not supported in VC++/VS.NET yet.
65 typedef unsigned char uint8_t; // C99 stdint.h not supported in VC++/VS.NET yet.
66 typedef signed short int16_t; // C99 stdint.h not supported in VC++/VS.NET yet.
67 typedef unsigned short uint16_t; // C99 stdint.h not supported in VC++/VS.NET yet.
68 typedef signed long int32_t; // C99 stdint.h not supported in VC++/VS.NET yet.
69 typedef unsigned long uint32_t; // C99 stdint.h not supported in VC++/VS.NET yet.
78 #include <sys/types.h>
79 #include <sys/socket.h>
80 #include <netinet/in.h>
85 #include <CoreServices/CoreServices.h>
87 #define WIN32_LEAN_AND_MEAN
93 #include "DNSServices.h"
94 #include "DNSServiceDiscovery.h"
96 //===========================================================================================================================
98 //===========================================================================================================================
100 #if( !TARGET_OS_MAC )
101 #define require_action_string( X, LABEL, ACTION, STR ) \
106 fprintf( stderr, "%s\n", ( STR ) ); \
112 #define require_string( X, LABEL, STR ) \
117 fprintf( stderr, "%s\n", ( STR ) ); \
123 #define require_noerr_string( ERR, LABEL, STR ) \
128 fprintf( stderr, "%s (%ld)\n", ( STR ), ( ERR ) ); \
134 //===========================================================================================================================
136 //===========================================================================================================================
138 int main( int argc
, char* argv
[] );
139 static void Usage( void );
140 static int ProcessArgs( int argc
, char* argv
[] );
141 static DNSStatus
ProcessPreset( int inPreset
);
144 static void SigIntHandler( int inSignalNumber
);
147 #if( defined( WINVER ) )
148 static BOOL WINAPI
ConsoleControlHandler( DWORD inControlEvent
);
151 static void BrowserCallBack( void *inContext
, DNSBrowserRef inRef
, DNSStatus inStatusCode
, const DNSBrowserEvent
*inEvent
);
152 static void ResolverCallBack( void *inContext
, DNSResolverRef inRef
, DNSStatus inStatusCode
, const DNSResolverEvent
*inEvent
);
155 RegistrationCallBack(
157 DNSRegistrationRef inRef
,
158 DNSStatus inStatusCode
,
159 const DNSRegistrationEvent
* inEvent
);
162 HostRegistrationCallBack(
164 DNSHostRegistrationRef inRef
,
165 DNSStatus inStatusCode
,
169 EmulatedBrowserCallBack(
170 DNSServiceBrowserReplyResultType inResult
,
173 const char * inDomain
,
174 DNSServiceDiscoveryReplyFlags inFlags
,
178 EmulatedDomainEnumerationCallBack(
179 DNSServiceDomainEnumerationReplyResultType inResult
,
180 const char * inDomain
,
181 DNSServiceDiscoveryReplyFlags inFlags
,
185 EmulatedResolverCallBack(
186 struct sockaddr
* inInterfaceAddr
,
187 struct sockaddr
* inAddr
,
188 const char * inTextRecord
,
189 DNSServiceDiscoveryReplyFlags inFlags
,
192 static void EmulatedRegistrationCallBack( DNSServiceRegistrationReplyErrorType inResult
, void *inContext
);
194 static char * IPv4ToString( DNSOpaque32 inIP
, char *outString
);
196 //===========================================================================================================================
198 //===========================================================================================================================
200 #if( defined( WINVER ) )
201 static volatile int gQuit
= 0;
204 static int gPrintTXTRecords
= 1;
208 typedef struct PresetData PresetData
;
216 #pragma mark == Presets ==
219 static const PresetData gPresets
[] =
221 /* 01 */ { 2, { "DNSServiceTest", "-bbd" } },
222 /* 02 */ { 4, { "DNSServiceTest", "-bs", "_airport._tcp", "local." } },
223 /* 03 */ { 4, { "DNSServiceTest", "-bs", "_xserveraid._tcp", "local." } },
224 /* 04 */ { 3, { "DNSServiceTest", "-rdb", "apple.com" } },
225 /* 05 */ { 7, { "DNSServiceTest", "-rs", "My Fake AirPort", "_airport._tcp", "local.", "1234", "My Fake Info" } },
226 /* 06 */ { 7, { "DNSServiceTest", "-rs", "My Fake Xserve RAID", "_xserveraid._tcp", "local.", "1234", "My Fake Info" } },
227 /* 07 */ { 7, { "DNSServiceTest", "-rs", "My Fake Web Server", "_http._tcp", "local.", "8080", "index.html" } },
228 /* 08 */ { 9, { "DNSServiceTest", "-rps", "www.apple.com", "17.254.0.91", "Apple Web Server", "_http._tcp", "local.", "80", "index.html" } },
231 const int gPresetsCount
= sizeof( gPresets
) / sizeof( gPresets
[ 0 ] );
237 //===========================================================================================================================
239 //===========================================================================================================================
241 int main( int argc
, char* argv
[] )
245 // Set up DNS Services and install a Console Control Handler to handle things like control-c signals.
247 err
= DNSServicesInitialize( kDNSFlagAdvertise
, 0 );
248 require_noerr_string( err
, exit
, "could not initialize DNSServiceTest" );
251 signal( SIGINT
, SigIntHandler
);
254 #if( defined( WINVER ) )
255 SetConsoleCtrlHandler( ConsoleControlHandler
, TRUE
);
258 ProcessArgs( argc
, argv
);
261 DNSServicesFinalize();
265 //===========================================================================================================================
267 //===========================================================================================================================
269 static void Usage( void )
271 fprintf( stderr
, "\n" );
272 fprintf( stderr
, "DNSServiceTest - DNS-SD Test Tool 1.0d1\n" );
273 fprintf( stderr
, "\n" );
274 fprintf( stderr
, " -bbd 'b'rowse for 'b'rowsing 'd'omains\n" );
275 fprintf( stderr
, " -brd 'b'rowse for 'r'egistration 'd'omains\n" );
276 fprintf( stderr
, " -bs <type> <domain> 'b'rowse for 's'ervices\n" );
277 fprintf( stderr
, " -lsi <name> <type> <domain> 'l'ookup 's'ervice 'i'nstance\n" );
278 fprintf( stderr
, " -rdb[d] <domain> 'r'egister 'd'omain for 'b'rowsing ['d'efault]\n" );
279 fprintf( stderr
, " -rdr[d] <domain> 'r'egister 'd'omain for 'r'egistration ['d'efault]\n" );
280 fprintf( stderr
, " -rs <name> <type> <domain> <port> <txt> 'r'egister 's'ervice\n" );
281 fprintf( stderr
, " -rps <host> <ip> <name> <type> <domain> <port> <txt> 'r'egister 'p'roxy 's'ervice\n" );
282 fprintf( stderr
, " -rnss <name> <type> <domain> 'r'egister 'n'o 's'uch 's'ervice\n" );
284 fprintf( stderr
, " -ebs <type> <domain> 'e'mulated 'b'rowse for 's'ervices\n" );
285 fprintf( stderr
, " -ebd <registration/browse> 'e'mulated 'b'rowse for 'd'omains\n" );
286 fprintf( stderr
, " -elsi <name> <type> <domain> 'e'mulated 'l'ookup 's'ervice 'i'nstance\n" );
287 fprintf( stderr
, " -ers <name> <type> <domain> <port> <txt> 'e'mulated 'r'egister 's'ervice\n" );
289 fprintf( stderr
, " -h[elp] 'h'elp\n" );
290 fprintf( stderr
, "\n" );
292 fprintf( stderr
, " -1 Preset 1 (browse for browsing domains) DNSServiceTest -bbd\n" );
293 fprintf( stderr
, " -2 Preset 2 (browse for AirPort) DNSServiceTest -bs \"_airport._tcp\" \"local.\"\n" );
294 fprintf( stderr
, " -3 Preset 3 (browse for Xserve RAID) DNSServiceTest -bs \"_xserveraid._tcp\" \"local.\"\n" );
295 fprintf( stderr
, " -4 Preset 4 (register apple.com domain) DNSServiceTest -rdb \"apple.com\"\n" );
296 fprintf( stderr
, " -5 Preset 5 (register fake AirPort) DNSServiceTest -rs \"My Fake AirPort\" \"_airport._tcp\" \"local.\" 1234 \"My Fake Info\"\n" );
297 fprintf( stderr
, " -6 Preset 6 (register fake Xserve RAID) DNSServiceTest -rs \"My Fake Xserve RAID\" \"_xserveraid._tcp\" \"local.\" 1234 \"My Fake Info\"\n" );
298 fprintf( stderr
, " -7 Preset 7 (register fake web server) DNSServiceTest -rs \"My Fake Web Server\" \"_http._tcp\" \"local.\" 8080 \"index.html\"\n" );
299 fprintf( stderr
, "\n" );
302 //===========================================================================================================================
304 //===========================================================================================================================
306 static int ProcessArgs( int argc
, char* argv
[] )
316 DNSBrowserRef browser
;
317 DNSResolverFlags resolverFlags
;
318 DNSDomainRegistrationType domainType
;
323 DNSNetworkAddress addr
;
324 dns_service_discovery_ref emulatedRef
;
326 // Parse the command line arguments (ignore first argument since it's just the program name).
328 require_action_string( argc
>= 2, exit
, err
= kDNSBadParamErr
, "no arguments specified" );
330 for( i
= 1; i
< argc
; ++i
)
332 if( strcmp( argv
[ i
], "-bbd" ) == 0 )
334 // 'b'rowse for 'b'rowsing 'd'omains
336 fprintf( stdout
, "browsing for browsing domains\n" );
338 err
= DNSBrowserCreate( 0, BrowserCallBack
, NULL
, &browser
);
339 require_noerr_string( err
, exit
, "create browser failed" );
341 err
= DNSBrowserStartDomainSearch( browser
, 0 );
342 require_noerr_string( err
, exit
, "start domain search failed" );
344 else if( strcmp( argv
[ i
], "-brd" ) == 0 )
346 // 'b'rowse for 'r'egistration 'd'omains
348 fprintf( stdout
, "browsing for registration domains\n" );
350 err
= DNSBrowserCreate( 0, BrowserCallBack
, NULL
, &browser
);
351 require_noerr_string( err
, exit
, "create browser failed" );
353 err
= DNSBrowserStartDomainSearch( browser
, kDNSBrowserFlagRegistrationDomainsOnly
);
354 require_noerr_string( err
, exit
, "start domain search failed" );
356 else if( strcmp( argv
[ i
], "-bs" ) == 0 )
358 // 'b'rowse for 's'ervices <type> <domain>
360 require_action_string( argc
> ( i
+ 2 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
364 if( ( domain
[ 0 ] == '\0' ) || ( ( domain
[ 0 ] == '.' ) && ( domain
[ 1 ] == '\0' ) ) )
368 fprintf( stdout
, "browsing for \"%s.%s\"\n", type
, domain
);
370 err
= DNSBrowserCreate( 0, BrowserCallBack
, NULL
, &browser
);
371 require_noerr_string( err
, exit
, "create browser failed" );
373 err
= DNSBrowserStartServiceSearch( browser
, kDNSBrowserFlagAutoResolve
, type
, domain
);
374 require_noerr_string( err
, exit
, "start service search failed" );
376 else if( strcmp( argv
[ i
], "-lsi" ) == 0 )
378 // 'l'ookup 's'ervice 'i'nstance <name> <type> <domain>
380 require_action_string( argc
> ( i
+ 3 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
385 if( ( domain
[ 0 ] == '\0' ) || ( ( domain
[ 0 ] == '.' ) && ( domain
[ 1 ] == '\0' ) ) )
389 fprintf( stdout
, "resolving \"%s.%s.%s\"\n", name
, type
, domain
);
391 resolverFlags
= kDNSResolverFlagOnlyIfUnique
|
392 kDNSResolverFlagAutoReleaseByName
;
393 err
= DNSResolverCreate( resolverFlags
, name
, type
, domain
, ResolverCallBack
, 0, NULL
, NULL
);
394 require_noerr_string( err
, exit
, "create resolver failed" );
396 else if( ( strcmp( argv
[ i
], "-rdb" ) == 0 ) || ( strcmp( argv
[ i
], "-rdbd" ) == 0 ) )
398 // 'r'egister 'd'omain for 'b'rowsing ['d'efault] <domain>
400 require_action_string( argc
> ( i
+ 1 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
401 if( strcmp( argv
[ i
], "-rdb" ) == 0 )
403 domainType
= kDNSDomainRegistrationTypeBrowse
;
408 domainType
= kDNSDomainRegistrationTypeBrowseDefault
;
413 if( ( domain
[ 0 ] == '\0' ) || ( ( domain
[ 0 ] == '.' ) && ( domain
[ 1 ] == '\0' ) ) )
417 fprintf( stdout
, "registering \"%s\" as %sbrowse domain\n", domain
, label
);
419 err
= DNSDomainRegistrationCreate( 0, domain
, domainType
, NULL
);
420 require_noerr_string( err
, exit
, "create domain registration failed" );
422 else if( ( strcmp( argv
[ i
], "-rdr" ) == 0 ) || ( strcmp( argv
[ i
], "-rdrd" ) == 0 ) )
424 // 'r'egister 'd'omain for 'r'egistration ['d'efault] <domain>
426 require_action_string( argc
> ( i
+ 1 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
427 if( strcmp( argv
[ i
], "-rdr" ) == 0 )
429 domainType
= kDNSDomainRegistrationTypeRegistration
;
434 domainType
= kDNSDomainRegistrationTypeRegistrationDefault
;
439 if( ( domain
[ 0 ] == '\0' ) || ( ( domain
[ 0 ] == '.' ) && ( domain
[ 1 ] == '\0' ) ) )
443 fprintf( stdout
, "registering \"%s\" as %sregistration domain\n", domain
, label
);
445 err
= DNSDomainRegistrationCreate( 0, domain
, domainType
, NULL
);
446 require_noerr_string( err
, exit
, "create domain registration failed" );
448 else if( strcmp( argv
[ i
], "-rs" ) == 0 )
450 // 'r'egister 's'ervice <name> <type> <domain> <port> <txt>
452 require_action_string( argc
> ( i
+ 5 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
456 domain
= argv
[ i
++ ];
457 port
= (uint16_t) atoi( argv
[ i
++ ] );
459 textSize
= strlen( text
);
460 if( ( domain
[ 0 ] == '\0' ) || ( ( domain
[ 0 ] == '.' ) && ( domain
[ 1 ] == '\0' ) ) )
464 fprintf( stdout
, "registering service \"%s.%s.%s\" port %d text \"%s\"\n", name
, type
, domain
, port
, text
);
466 err
= DNSRegistrationCreate( 0, name
, type
, domain
, (DNSPort
) port
, text
, (DNSCount
) textSize
, NULL
, NULL
,
467 RegistrationCallBack
, NULL
, NULL
);
468 require_noerr_string( err
, exit
, "create registration failed" );
470 else if( strcmp( argv
[ i
], "-rps" ) == 0 )
472 DNSHostRegistrationFlags hostFlags
;
474 // 'r'egister 'p'roxy 's'ervice <host> <ip> <name> <type> <domain> <port> <txt>
476 require_action_string( argc
> ( i
+ 7 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
482 domain
= argv
[ i
++ ];
483 port
= (uint16_t) atoi( argv
[ i
++ ] );
485 textSize
= strlen( text
);
486 if( ( domain
[ 0 ] == '\0' ) || ( ( domain
[ 0 ] == '.' ) && ( domain
[ 1 ] == '\0' ) ) )
491 sscanf( ip
, "%u.%u.%u.%u", &b
[ 0 ], &b
[ 1 ], &b
[ 2 ], &b
[ 3 ] );
492 addr
.addressType
= kDNSNetworkAddressTypeIPv4
;
493 addr
.u
.ipv4
.addr
.v8
[ 0 ] = (DNSUInt8
) b
[ 0 ];
494 addr
.u
.ipv4
.addr
.v8
[ 1 ] = (DNSUInt8
) b
[ 1 ];
495 addr
.u
.ipv4
.addr
.v8
[ 2 ] = (DNSUInt8
) b
[ 2 ];
496 addr
.u
.ipv4
.addr
.v8
[ 3 ] = (DNSUInt8
) b
[ 3 ];
498 fprintf( stdout
, "registering proxy service \"%s.%s.%s\" port %d text \"%s\"\n", name
, type
, domain
, port
, text
);
500 hostFlags
= kDNSHostRegistrationFlagOnlyIfNotFound
| kDNSHostRegistrationFlagAutoRenameOnConflict
;
501 err
= DNSHostRegistrationCreate( hostFlags
, host
, domain
, &addr
, NULL
,
502 HostRegistrationCallBack
, NULL
, NULL
);
503 require_noerr_string( err
, exit
, "create host registration failed" );
505 err
= DNSRegistrationCreate( 0, name
, type
, domain
, (DNSPort
) port
, text
, (DNSCount
) textSize
, host
, NULL
,
506 RegistrationCallBack
, NULL
, NULL
);
507 require_noerr_string( err
, exit
, "create registration failed" );
509 else if( strcmp( argv
[ i
], "-rnss" ) == 0 )
511 // 'r'egister 'n'o 's'uch 's'ervice <name> <type> <domain>
513 require_action_string( argc
> ( i
+ 3 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
517 domain
= argv
[ i
++ ];
518 if( ( domain
[ 0 ] == '\0' ) || ( ( domain
[ 0 ] == '.' ) && ( domain
[ 1 ] == '\0' ) ) )
522 fprintf( stdout
, "registering no-such-service \"%s.%s.%s\"\n", name
, type
, domain
);
524 err
= DNSNoSuchServiceRegistrationCreate( 0, name
, type
, domain
, NULL
, RegistrationCallBack
, NULL
, NULL
);
525 require_noerr_string( err
, exit
, "create no-such-service registration failed" );
527 else if( strcmp( argv
[ i
], "-ebs" ) == 0 )
529 // 'e'mulated 'b'rowse for 's'ervices <type> <domain>
531 require_action_string( argc
> ( i
+ 2 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
535 if( ( domain
[ 0 ] == '\0' ) || ( ( domain
[ 0 ] == '.' ) && ( domain
[ 1 ] == '\0' ) ) )
539 fprintf( stdout
, "emulated browsing for \"%s.%s\"\n", type
, domain
);
541 emulatedRef
= DNSServiceBrowserCreate( type
, domain
, EmulatedBrowserCallBack
, NULL
);
542 require_action_string( emulatedRef
, exit
, err
= kDNSUnknownErr
, "create emulated browser failed" );
544 else if( strcmp( argv
[ i
], "-ebd" ) == 0 )
546 int registrationOnly
;
548 // 'e'mulated 'b'rowse for 'd'omains <registration/browse>
550 require_action_string( argc
> ( i
+ 1 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
553 if( strcmp( type
, "registration" ) == 0 )
555 registrationOnly
= 1;
557 else if( strcmp( type
, "browse" ) == 0 )
559 registrationOnly
= 0;
563 require_action_string( 0, exit
, err
= kDNSBadParamErr
, "invalid browse type" );
565 fprintf( stdout
, "emulated browsing for %s domains\n", type
);
567 emulatedRef
= DNSServiceDomainEnumerationCreate( registrationOnly
, EmulatedDomainEnumerationCallBack
, NULL
);
568 require_action_string( emulatedRef
, exit
, err
= kDNSUnknownErr
, "create emulated domain browser failed" );
570 else if( strcmp( argv
[ i
], "-elsi" ) == 0 )
572 // 'e'mulated 'l'ookup 's'ervice 'i'nstance <name> <type> <domain>
574 require_action_string( argc
> ( i
+ 3 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
579 if( ( domain
[ 0 ] == '\0' ) || ( ( domain
[ 0 ] == '.' ) && ( domain
[ 1 ] == '\0' ) ) )
583 fprintf( stdout
, "emulated resolving \"%s.%s.%s\"\n", name
, type
, domain
);
585 emulatedRef
= DNSServiceResolverResolve( name
, type
, domain
, EmulatedResolverCallBack
, NULL
);
586 require_action_string( emulatedRef
, exit
, err
= kDNSUnknownErr
, "create emulated resolver failed" );
588 else if( strcmp( argv
[ i
], "-ers" ) == 0 )
590 // 'e'mulated 'r'egister 's'ervice <name> <type> <domain> <port> <txt>
592 require_action_string( argc
> ( i
+ 5 ), exit
, err
= kDNSBadParamErr
, "missing arguments" );
596 domain
= argv
[ i
++ ];
597 port
= (uint16_t) atoi( argv
[ i
++ ] );
599 textSize
= strlen( text
);
600 if( ( domain
[ 0 ] == '\0' ) || ( ( domain
[ 0 ] == '.' ) && ( domain
[ 1 ] == '\0' ) ) )
604 fprintf( stdout
, "registering service \"%s.%s.%s\" port %d text \"%s\"\n", name
, type
, domain
, port
, text
);
606 emulatedRef
= DNSServiceRegistrationCreate( name
, type
, domain
, htons( port
), text
,
607 EmulatedRegistrationCallBack
, NULL
);
608 require_action_string( emulatedRef
, exit
, err
= kDNSUnknownErr
, "create emulated registration failed" );
610 else if( ( argv
[ i
][ 0 ] == '-' ) && isdigit( argv
[ i
][ 1 ] ) )
614 ProcessPreset( atoi( &argv
[ i
][ 1 ] ) );
618 else if( strcmp( argv
[ i
], "-q" ) == 0 )
620 // Quiet (no text records)
622 gPrintTXTRecords
= 0;
624 else if( ( strcmp( argv
[ i
], "-help" ) == 0 ) || ( strcmp( argv
[ i
], "-h" ) == 0 ) )
634 // Unknown parameter.
636 require_action_string( 0, exit
, err
= kDNSBadParamErr
, "unknown parameter" );
641 // Run until control-C'd.
647 #if( defined( WINVER ) )
664 //===========================================================================================================================
666 //===========================================================================================================================
668 static DNSStatus
ProcessPreset( int inPreset
)
672 require_action_string( ( inPreset
> 0 ) && ( inPreset
<= gPresetsCount
), exit
, err
= kDNSBadParamErr
, "invalid preset" );
674 err
= ProcessArgs( gPresets
[ inPreset
- 1 ].argc
, (char **) gPresets
[ inPreset
- 1 ].argv
);
681 //===========================================================================================================================
683 //===========================================================================================================================
685 static void SigIntHandler( int inSignalNumber
)
687 DNS_UNUSED( inSignalNumber
);
689 signal( SIGINT
, SIG_DFL
);
690 CFRunLoopStop( CFRunLoopGetCurrent() );
694 #if( defined( WINVER ) )
695 //===========================================================================================================================
696 // ConsoleControlHandler
697 //===========================================================================================================================
699 static BOOL WINAPI
ConsoleControlHandler( DWORD inControlEvent
)
704 switch( inControlEvent
)
707 case CTRL_BREAK_EVENT
:
708 case CTRL_CLOSE_EVENT
:
709 case CTRL_LOGOFF_EVENT
:
710 case CTRL_SHUTDOWN_EVENT
:
722 //===========================================================================================================================
724 //===========================================================================================================================
726 static void BrowserCallBack( void *inContext
, DNSBrowserRef inRef
, DNSStatus inStatusCode
, const DNSBrowserEvent
*inEvent
)
731 DNS_UNUSED( inContext
);
733 DNS_UNUSED( inStatusCode
);
735 switch( inEvent
->type
)
737 case kDNSBrowserEventTypeRelease
:
740 case kDNSBrowserEventTypeAddDomain
:
741 fprintf( stdout
, "domain \"%s\" added on interface 0x%p (%s)\n",
742 inEvent
->data
.addDomain
.domain
,
743 (int) inEvent
->data
.addDomain
.interfaceID
,
744 IPv4ToString( inEvent
->data
.addDomain
.interfaceIP
.u
.ipv4
.addr
, ifIP
) );
747 case kDNSBrowserEventTypeAddDefaultDomain
:
748 fprintf( stdout
, "default domain \"%s\" added on interface 0x%p (%s)\n",
749 inEvent
->data
.addDefaultDomain
.domain
,
750 (int) inEvent
->data
.addDefaultDomain
.interfaceID
,
751 IPv4ToString( inEvent
->data
.addDefaultDomain
.interfaceIP
.u
.ipv4
.addr
, ifIP
) );
754 case kDNSBrowserEventTypeRemoveDomain
:
755 fprintf( stdout
, "domain \"%s\" removed on interface 0x%p (%s)\n",
756 inEvent
->data
.removeDomain
.domain
,
757 (int) inEvent
->data
.removeDomain
.interfaceID
,
758 IPv4ToString( inEvent
->data
.removeDomain
.interfaceIP
.u
.ipv4
.addr
, ifIP
) );
761 case kDNSBrowserEventTypeAddService
:
762 fprintf( stdout
, "service \"%s.%s%s\" added on interface 0x%p (%s)\n",
763 inEvent
->data
.addService
.name
,
764 inEvent
->data
.addService
.type
,
765 inEvent
->data
.addService
.domain
,
766 (int) inEvent
->data
.addService
.interfaceID
,
767 IPv4ToString( inEvent
->data
.addService
.interfaceIP
.u
.ipv4
.addr
, ifIP
) );
770 case kDNSBrowserEventTypeRemoveService
:
771 fprintf( stdout
, "service \"%s.%s%s\" removed on interface 0x%p (%s)\n",
772 inEvent
->data
.removeService
.name
,
773 inEvent
->data
.removeService
.type
,
774 inEvent
->data
.removeService
.domain
,
775 (int) inEvent
->data
.removeService
.interfaceID
,
776 IPv4ToString( inEvent
->data
.removeService
.interfaceIP
.u
.ipv4
.addr
, ifIP
) );
779 case kDNSBrowserEventTypeResolved
:
785 fprintf( stdout
, "resolved \"%s.%s%s\" to \"%s\" (%s:%u) on interface 0x%p (%s)%s\n",
786 inEvent
->data
.resolved
->name
,
787 inEvent
->data
.resolved
->type
,
788 inEvent
->data
.resolved
->domain
,
789 inEvent
->data
.resolved
->hostName
,
790 IPv4ToString( inEvent
->data
.resolved
->address
.u
.ipv4
.addr
, ip
),
791 ( inEvent
->data
.resolved
->address
.u
.ipv4
.port
.v8
[ 0 ] << 8 ) |
792 inEvent
->data
.resolved
->address
.u
.ipv4
.port
.v8
[ 1 ],
793 (int) inEvent
->data
.resolved
->interfaceID
,
794 IPv4ToString( inEvent
->data
.resolved
->interfaceIP
.u
.ipv4
.addr
, ifIP
),
795 ( inEvent
->data
.resolved
->textRecordRawSize
> 0 ) ? " with text:" : "" );
797 p
= (const uint8_t *) inEvent
->data
.resolved
->textRecordRaw
;
798 end
= p
+ inEvent
->data
.resolved
->textRecordRawSize
;
801 if( gPrintTXTRecords
)
808 if( ( p
+ size
) > end
)
810 fprintf( stdout
, "\n### MALFORMED TXT RECORD (length byte too big for record)\n\n" );
813 fprintf( stdout
, "%5d (%3d bytes): \"%.*s\"\n", i
, size
, size
, p
);
817 fprintf( stdout
, "\n" );
827 //===========================================================================================================================
829 //===========================================================================================================================
831 static void ResolverCallBack( void *inContext
, DNSResolverRef inRef
, DNSStatus inStatusCode
, const DNSResolverEvent
*inEvent
)
836 DNS_UNUSED( inContext
);
838 DNS_UNUSED( inStatusCode
);
840 switch( inEvent
->type
)
842 case kDNSResolverEventTypeResolved
:
848 fprintf( stdout
, "resolved \"%s.%s%s\" to \"%s\" (%s:%u) on interface 0x%p (%s)%s\n",
849 inEvent
->data
.resolved
.name
,
850 inEvent
->data
.resolved
.type
,
851 inEvent
->data
.resolved
.domain
,
852 inEvent
->data
.resolved
.hostName
,
853 IPv4ToString( inEvent
->data
.resolved
.address
.u
.ipv4
.addr
, ip
),
854 ( inEvent
->data
.resolved
.address
.u
.ipv4
.port
.v8
[ 0 ] << 8 ) |
855 inEvent
->data
.resolved
.address
.u
.ipv4
.port
.v8
[ 1 ],
856 (int) inEvent
->data
.resolved
.interfaceID
,
857 IPv4ToString( inEvent
->data
.resolved
.interfaceIP
.u
.ipv4
.addr
, ifIP
),
858 ( inEvent
->data
.resolved
.textRecordRawSize
> 0 ) ? " with text:" : "" );
860 p
= (const uint8_t *) inEvent
->data
.resolved
.textRecordRaw
;
861 end
= p
+ inEvent
->data
.resolved
.textRecordRawSize
;
864 if( gPrintTXTRecords
)
871 if( ( p
+ size
) > end
)
873 fprintf( stdout
, "\n### MALFORMED TXT RECORD (length byte too big for record)\n\n" );
876 fprintf( stdout
, "%5d (%3d bytes): \"%.*s\"\n", i
, size
, size
, p
);
880 fprintf( stdout
, "\n" );
885 case kDNSResolverEventTypeRelease
:
893 //===========================================================================================================================
894 // RegistrationCallBack
895 //===========================================================================================================================
898 RegistrationCallBack(
900 DNSRegistrationRef inRef
,
901 DNSStatus inStatusCode
,
902 const DNSRegistrationEvent
* inEvent
)
904 DNS_UNUSED( inContext
);
906 DNS_UNUSED( inStatusCode
);
908 switch( inEvent
->type
)
910 case kDNSRegistrationEventTypeRelease
:
913 case kDNSRegistrationEventTypeRegistered
:
914 fprintf( stdout
, "name registered and active\n" );
917 case kDNSRegistrationEventTypeNameCollision
:
918 fprintf( stdout
, "name in use, please choose another name\n" );
926 //===========================================================================================================================
927 // HostRegistrationCallBack
928 //===========================================================================================================================
931 HostRegistrationCallBack(
933 DNSHostRegistrationRef inRef
,
934 DNSStatus inStatusCode
,
937 DNS_UNUSED( inContext
);
939 DNS_UNUSED( inData
);
941 if( inStatusCode
== kDNSNoErr
)
943 fprintf( stdout
, "host name registered and active\n" );
945 else if( inStatusCode
== kDNSNameConflictErr
)
947 fprintf( stdout
, "host name in use, please choose another name\n" );
951 fprintf( stdout
, "unknown host registration status (%ld)\n", inStatusCode
);
955 //===========================================================================================================================
956 // EmulatedBrowserCallBack
957 //===========================================================================================================================
960 EmulatedBrowserCallBack(
961 DNSServiceBrowserReplyResultType inResult
,
964 const char * inDomain
,
965 DNSServiceDiscoveryReplyFlags inFlags
,
968 DNS_UNUSED( inFlags
);
969 DNS_UNUSED( inContext
);
971 if( inResult
== DNSServiceBrowserReplyAddInstance
)
973 fprintf( stdout
, "\"%s.%s%s\" service added emulated\n", inName
, inType
, inDomain
);
975 else if( inResult
== DNSServiceBrowserReplyRemoveInstance
)
977 fprintf( stdout
, "\"%s.%s%s\" service removed emulated\n", inName
, inType
, inDomain
);
981 fprintf( stdout
, "### unknown emulated browser callback result (%d)\n", inResult
);
985 //===========================================================================================================================
986 // EmulatedDomainEnumerationCallBack
987 //===========================================================================================================================
990 EmulatedDomainEnumerationCallBack(
991 DNSServiceDomainEnumerationReplyResultType inResult
,
992 const char * inDomain
,
993 DNSServiceDiscoveryReplyFlags inFlags
,
996 DNS_UNUSED( inFlags
);
997 DNS_UNUSED( inContext
);
999 if( inResult
== DNSServiceDomainEnumerationReplyAddDomain
)
1001 fprintf( stdout
, "\"%s\" domain added emulated\n", inDomain
);
1003 else if( inResult
== DNSServiceDomainEnumerationReplyAddDomainDefault
)
1005 fprintf( stdout
, "\"%s\" default domain added emulated\n", inDomain
);
1007 else if( inResult
== DNSServiceDomainEnumerationReplyRemoveDomain
)
1009 fprintf( stdout
, "\"%s\" domain removed emulated\n", inDomain
);
1013 fprintf( stdout
, "### unknown emulated domain enumeration callback result (%d)\n", inResult
);
1017 //===========================================================================================================================
1018 // EmulatedResolverCallBack
1019 //===========================================================================================================================
1022 EmulatedResolverCallBack(
1023 struct sockaddr
* inInterfaceAddr
,
1024 struct sockaddr
* inAddr
,
1025 const char * inTextRecord
,
1026 DNSServiceDiscoveryReplyFlags inFlags
,
1029 struct sockaddr_in
* ifSin4
;
1030 struct sockaddr_in
* sin4
;
1034 DNS_UNUSED( inFlags
);
1035 DNS_UNUSED( inContext
);
1037 ifSin4
= (struct sockaddr_in
*) inInterfaceAddr
;
1038 sin4
= (struct sockaddr_in
*) inAddr
;
1040 fprintf( stdout
, "service resolved to %s:%d on interface %s with text \"%s\"\n",
1041 IPv4ToString( *( (DNSOpaque32
*) &sin4
->sin_addr
.s_addr
), ip
),
1042 ntohs( sin4
->sin_port
),
1043 IPv4ToString( *( (DNSOpaque32
*) &ifSin4
->sin_addr
.s_addr
), ifIP
),
1044 inTextRecord
? inTextRecord
: "" );
1047 //===========================================================================================================================
1048 // EmulatedResolverCallBack
1049 //===========================================================================================================================
1051 static void EmulatedRegistrationCallBack( DNSServiceRegistrationReplyErrorType inResult
, void *inContext
)
1053 DNS_UNUSED( inContext
);
1055 if( inResult
== kDNSServiceDiscoveryNoError
)
1057 fprintf( stdout
, "service name registered successfully\n" );
1061 fprintf( stdout
, "service registration failed( %d)\n", inResult
);
1065 //===========================================================================================================================
1067 //===========================================================================================================================
1069 static char * IPv4ToString( DNSOpaque32 inIP
, char *outString
)
1071 sprintf( outString
, "%u.%u.%u.%u", inIP
.v8
[ 0 ], inIP
.v8
[ 1 ], inIP
.v8
[ 2 ], inIP
.v8
[ 3 ] );
1072 return( outString
);