]>
Commit | Line | Data |
---|---|---|
c9b9ae52 | 1 | /* |
8e92c31c | 2 | * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved. |
c9b9ae52 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
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 | |
11 | * file. | |
12 | * | |
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. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | ||
23 | Change History (most recent first): | |
24 | ||
25 | $Log: Tool.c,v $ | |
7f0064bd A |
26 | Revision 1.3 2004/09/16 01:58:25 cheshire |
27 | Fix compiler warnings | |
28 | ||
29 | Revision 1.2 2004/07/13 21:24:28 rpantos | |
30 | Fix for <rdar://problem/3701120>. | |
31 | ||
32 | Revision 1.1 2004/06/18 04:07:54 rpantos | |
33 | Move up one level | |
34 | ||
8e92c31c A |
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. | |
37 | ||
38 | Revision 1.11 2004/01/30 03:04:32 bradley | |
39 | Updated for latest changes to mDNSWindows. | |
40 | ||
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. | |
43 | ||
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. | |
46 | ||
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. | |
49 | ||
c9b9ae52 A |
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. | |
52 | ||
53 | Revision 1.6 2003/08/20 06:50:55 bradley | |
7f0064bd | 54 | Updated to latest internal version of the mDNSCore code: Re-did everything to support |
c9b9ae52 A |
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. | |
57 | ||
58 | */ | |
59 | ||
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". | |
64 | ||
65 | // No stdint.h with Visual C++ so emulate it here. | |
66 | ||
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. | |
73 | #else | |
74 | #include <stdint.h> | |
75 | #endif | |
76 | ||
77 | #include <stdio.h> | |
78 | #include <stdlib.h> | |
79 | ||
80 | #if( __MACH__ ) | |
81 | #include <sys/types.h> | |
82 | #include <sys/socket.h> | |
83 | #include <netinet/in.h> | |
84 | ||
85 | #include <signal.h> | |
86 | #include <unistd.h> | |
87 | ||
88 | #include <CoreServices/CoreServices.h> | |
89 | #else | |
90 | #define WIN32_LEAN_AND_MEAN | |
91 | ||
92 | #include <winsock2.h> | |
93 | #include <windows.h> | |
94 | #endif | |
95 | ||
96 | #include "DNSServices.h" | |
97 | #include "DNSServiceDiscovery.h" | |
98 | ||
99 | //=========================================================================================================================== | |
100 | // Macros | |
101 | //=========================================================================================================================== | |
102 | ||
103 | #if( !TARGET_OS_MAC ) | |
104 | #define require_action_string( X, LABEL, ACTION, STR ) \ | |
105 | do \ | |
106 | { \ | |
107 | if( !( X ) ) \ | |
108 | { \ | |
109 | fprintf( stderr, "%s\n", ( STR ) ); \ | |
110 | { ACTION; } \ | |
111 | goto LABEL; \ | |
112 | } \ | |
113 | } while( 0 ) | |
114 | ||
115 | #define require_string( X, LABEL, STR ) \ | |
116 | do \ | |
117 | { \ | |
118 | if( !( X ) ) \ | |
119 | { \ | |
120 | fprintf( stderr, "%s\n", ( STR ) ); \ | |
121 | goto LABEL; \ | |
122 | \ | |
123 | } \ | |
124 | } while( 0 ) | |
125 | ||
126 | #define require_noerr_string( ERR, LABEL, STR ) \ | |
127 | do \ | |
128 | { \ | |
129 | if( ( ERR ) != 0 ) \ | |
130 | { \ | |
131 | fprintf( stderr, "%s (%ld)\n", ( STR ), ( ERR ) ); \ | |
132 | goto LABEL; \ | |
133 | } \ | |
134 | } while( 0 ) | |
135 | #endif | |
136 | ||
137 | //=========================================================================================================================== | |
138 | // Prototypes | |
139 | //=========================================================================================================================== | |
140 | ||
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 ); | |
145 | ||
146 | #if( __MACH__ ) | |
147 | static void SigIntHandler( int inSignalNumber ); | |
148 | #endif | |
149 | ||
150 | #if( defined( WINVER ) ) | |
151 | static BOOL WINAPI ConsoleControlHandler( DWORD inControlEvent ); | |
152 | #endif | |
153 | ||
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 ); | |
156 | ||
157 | static void | |
158 | RegistrationCallBack( | |
159 | void * inContext, | |
160 | DNSRegistrationRef inRef, | |
161 | DNSStatus inStatusCode, | |
162 | const DNSRegistrationEvent * inEvent ); | |
163 | ||
164 | static void | |
165 | HostRegistrationCallBack( | |
166 | void * inContext, | |
167 | DNSHostRegistrationRef inRef, | |
168 | DNSStatus inStatusCode, | |
169 | void * inData ); | |
170 | ||
171 | static void | |
172 | EmulatedBrowserCallBack( | |
173 | DNSServiceBrowserReplyResultType inResult, | |
174 | const char * inName, | |
175 | const char * inType, | |
176 | const char * inDomain, | |
177 | DNSServiceDiscoveryReplyFlags inFlags, | |
178 | void * inContext ); | |
179 | ||
180 | static void | |
181 | EmulatedDomainEnumerationCallBack( | |
182 | DNSServiceDomainEnumerationReplyResultType inResult, | |
183 | const char * inDomain, | |
184 | DNSServiceDiscoveryReplyFlags inFlags, | |
185 | void * inContext ); | |
186 | ||
187 | static void | |
188 | EmulatedResolverCallBack( | |
189 | struct sockaddr * inInterfaceAddr, | |
190 | struct sockaddr * inAddr, | |
191 | const char * inTextRecord, | |
192 | DNSServiceDiscoveryReplyFlags inFlags, | |
193 | void * inContext ); | |
194 | ||
195 | static void EmulatedRegistrationCallBack( DNSServiceRegistrationReplyErrorType inResult, void *inContext ); | |
196 | ||
197 | static char * IPv4ToString( DNSOpaque32 inIP, char *outString ); | |
198 | ||
199 | //=========================================================================================================================== | |
200 | // Globals | |
201 | //=========================================================================================================================== | |
202 | ||
203 | #if( defined( WINVER ) ) | |
204 | static volatile int gQuit = 0; | |
205 | #endif | |
206 | ||
207 | static int gPrintTXTRecords = 1; | |
208 | ||
209 | // Presets | |
210 | ||
211 | typedef struct PresetData PresetData; | |
212 | struct PresetData | |
213 | { | |
214 | int argc; | |
215 | char * argv[ 16 ]; | |
216 | }; | |
217 | ||
218 | #if 0 | |
219 | #pragma mark == Presets == | |
220 | #endif | |
221 | ||
222 | static const PresetData gPresets[] = | |
223 | { | |
7f0064bd A |
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" } }, | |
c9b9ae52 A |
232 | }; |
233 | ||
234 | const int gPresetsCount = sizeof( gPresets ) / sizeof( gPresets[ 0 ] ); | |
235 | ||
236 | #if 0 | |
237 | #pragma mark - | |
238 | #endif | |
239 | ||
240 | //=========================================================================================================================== | |
241 | // main | |
242 | //=========================================================================================================================== | |
243 | ||
244 | int main( int argc, char* argv[] ) | |
245 | { | |
246 | DNSStatus err; | |
247 | ||
248 | // Set up DNS Services and install a Console Control Handler to handle things like control-c signals. | |
249 | ||
250 | err = DNSServicesInitialize( kDNSFlagAdvertise, 0 ); | |
7f0064bd | 251 | require_noerr_string( err, exit, "could not initialize DNSServiceTest" ); |
c9b9ae52 A |
252 | |
253 | #if( __MACH__ ) | |
254 | signal( SIGINT, SigIntHandler ); | |
255 | #endif | |
256 | ||
257 | #if( defined( WINVER ) ) | |
258 | SetConsoleCtrlHandler( ConsoleControlHandler, TRUE ); | |
259 | #endif | |
260 | ||
261 | ProcessArgs( argc, argv ); | |
262 | ||
263 | exit: | |
264 | DNSServicesFinalize(); | |
265 | return( err ); | |
266 | } | |
267 | ||
268 | //=========================================================================================================================== | |
269 | // Usage | |
270 | //=========================================================================================================================== | |
271 | ||
272 | static void Usage( void ) | |
273 | { | |
274 | fprintf( stderr, "\n" ); | |
7f0064bd | 275 | fprintf( stderr, "DNSServiceTest - DNS-SD Test Tool 1.0d1\n" ); |
c9b9ae52 A |
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" ); | |
286 | ||
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" ); | |
291 | ||
292 | fprintf( stderr, " -h[elp] 'h'elp\n" ); | |
293 | fprintf( stderr, "\n" ); | |
294 | ||
7f0064bd A |
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" ); | |
c9b9ae52 A |
302 | fprintf( stderr, "\n" ); |
303 | } | |
304 | ||
305 | //=========================================================================================================================== | |
306 | // ProcessArgs | |
307 | //=========================================================================================================================== | |
308 | ||
309 | static int ProcessArgs( int argc, char* argv[] ) | |
310 | { | |
311 | DNSStatus err; | |
312 | int i; | |
313 | const char * name; | |
314 | const char * type; | |
315 | const char * domain; | |
8e92c31c | 316 | uint16_t port; |
c9b9ae52 A |
317 | const char * text; |
318 | size_t textSize; | |
319 | DNSBrowserRef browser; | |
320 | DNSResolverFlags resolverFlags; | |
321 | DNSDomainRegistrationType domainType; | |
322 | const char * label; | |
323 | const char * host; | |
324 | const char * ip; | |
325 | unsigned int b[ 4 ]; | |
326 | DNSNetworkAddress addr; | |
327 | dns_service_discovery_ref emulatedRef; | |
328 | ||
329 | // Parse the command line arguments (ignore first argument since it's just the program name). | |
330 | ||
331 | require_action_string( argc >= 2, exit, err = kDNSBadParamErr, "no arguments specified" ); | |
332 | ||
333 | for( i = 1; i < argc; ++i ) | |
334 | { | |
335 | if( strcmp( argv[ i ], "-bbd" ) == 0 ) | |
336 | { | |
337 | // 'b'rowse for 'b'rowsing 'd'omains | |
338 | ||
339 | fprintf( stdout, "browsing for browsing domains\n" ); | |
340 | ||
341 | err = DNSBrowserCreate( 0, BrowserCallBack, NULL, &browser ); | |
342 | require_noerr_string( err, exit, "create browser failed" ); | |
343 | ||
344 | err = DNSBrowserStartDomainSearch( browser, 0 ); | |
345 | require_noerr_string( err, exit, "start domain search failed" ); | |
346 | } | |
347 | else if( strcmp( argv[ i ], "-brd" ) == 0 ) | |
348 | { | |
349 | // 'b'rowse for 'r'egistration 'd'omains | |
350 | ||
351 | fprintf( stdout, "browsing for registration domains\n" ); | |
352 | ||
353 | err = DNSBrowserCreate( 0, BrowserCallBack, NULL, &browser ); | |
354 | require_noerr_string( err, exit, "create browser failed" ); | |
355 | ||
356 | err = DNSBrowserStartDomainSearch( browser, kDNSBrowserFlagRegistrationDomainsOnly ); | |
357 | require_noerr_string( err, exit, "start domain search failed" ); | |
358 | } | |
359 | else if( strcmp( argv[ i ], "-bs" ) == 0 ) | |
360 | { | |
361 | // 'b'rowse for 's'ervices <type> <domain> | |
362 | ||
363 | require_action_string( argc > ( i + 2 ), exit, err = kDNSBadParamErr, "missing arguments" ); | |
364 | ++i; | |
365 | type = argv[ i++ ]; | |
366 | domain = argv[ i ]; | |
367 | if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) ) | |
368 | { | |
369 | domain = "local."; | |
370 | } | |
371 | fprintf( stdout, "browsing for \"%s.%s\"\n", type, domain ); | |
372 | ||
373 | err = DNSBrowserCreate( 0, BrowserCallBack, NULL, &browser ); | |
374 | require_noerr_string( err, exit, "create browser failed" ); | |
375 | ||
376 | err = DNSBrowserStartServiceSearch( browser, kDNSBrowserFlagAutoResolve, type, domain ); | |
377 | require_noerr_string( err, exit, "start service search failed" ); | |
378 | } | |
379 | else if( strcmp( argv[ i ], "-lsi" ) == 0 ) | |
380 | { | |
381 | // 'l'ookup 's'ervice 'i'nstance <name> <type> <domain> | |
382 | ||
383 | require_action_string( argc > ( i + 3 ), exit, err = kDNSBadParamErr, "missing arguments" ); | |
384 | ++i; | |
385 | name = argv[ i++ ]; | |
386 | type = argv[ i++ ]; | |
387 | domain = argv[ i ]; | |
388 | if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) ) | |
389 | { | |
390 | domain = "local."; | |
391 | } | |
392 | fprintf( stdout, "resolving \"%s.%s.%s\"\n", name, type, domain ); | |
393 | ||
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" ); | |
398 | } | |
399 | else if( ( strcmp( argv[ i ], "-rdb" ) == 0 ) || ( strcmp( argv[ i ], "-rdbd" ) == 0 ) ) | |
400 | { | |
401 | // 'r'egister 'd'omain for 'b'rowsing ['d'efault] <domain> | |
402 | ||
403 | require_action_string( argc > ( i + 1 ), exit, err = kDNSBadParamErr, "missing arguments" ); | |
404 | if( strcmp( argv[ i ], "-rdb" ) == 0 ) | |
405 | { | |
406 | domainType = kDNSDomainRegistrationTypeBrowse; | |
407 | label = ""; | |
408 | } | |
409 | else | |
410 | { | |
411 | domainType = kDNSDomainRegistrationTypeBrowseDefault; | |
412 | label = "default "; | |
413 | } | |
414 | ++i; | |
415 | domain = argv[ i ]; | |
416 | if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) ) | |
417 | { | |
418 | domain = "local."; | |
419 | } | |
420 | fprintf( stdout, "registering \"%s\" as %sbrowse domain\n", domain, label ); | |
421 | ||
422 | err = DNSDomainRegistrationCreate( 0, domain, domainType, NULL ); | |
423 | require_noerr_string( err, exit, "create domain registration failed" ); | |
424 | } | |
425 | else if( ( strcmp( argv[ i ], "-rdr" ) == 0 ) || ( strcmp( argv[ i ], "-rdrd" ) == 0 ) ) | |
426 | { | |
427 | // 'r'egister 'd'omain for 'r'egistration ['d'efault] <domain> | |
428 | ||
429 | require_action_string( argc > ( i + 1 ), exit, err = kDNSBadParamErr, "missing arguments" ); | |
430 | if( strcmp( argv[ i ], "-rdr" ) == 0 ) | |
431 | { | |
432 | domainType = kDNSDomainRegistrationTypeRegistration; | |
433 | label = ""; | |
434 | } | |
435 | else | |
436 | { | |
437 | domainType = kDNSDomainRegistrationTypeRegistrationDefault; | |
438 | label = "default "; | |
439 | } | |
440 | ++i; | |
441 | domain = argv[ i ]; | |
442 | if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) ) | |
443 | { | |
444 | domain = "local."; | |
445 | } | |
446 | fprintf( stdout, "registering \"%s\" as %sregistration domain\n", domain, label ); | |
447 | ||
448 | err = DNSDomainRegistrationCreate( 0, domain, domainType, NULL ); | |
449 | require_noerr_string( err, exit, "create domain registration failed" ); | |
450 | } | |
451 | else if( strcmp( argv[ i ], "-rs" ) == 0 ) | |
452 | { | |
453 | // 'r'egister 's'ervice <name> <type> <domain> <port> <txt> | |
454 | ||
455 | require_action_string( argc > ( i + 5 ), exit, err = kDNSBadParamErr, "missing arguments" ); | |
456 | ++i; | |
457 | name = argv[ i++ ]; | |
458 | type = argv[ i++ ]; | |
459 | domain = argv[ i++ ]; | |
8e92c31c | 460 | port = (uint16_t) atoi( argv[ i++ ] ); |
c9b9ae52 A |
461 | text = argv[ i ]; |
462 | textSize = strlen( text ); | |
8e92c31c | 463 | if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) ) |
c9b9ae52 A |
464 | { |
465 | domain = "local."; | |
466 | } | |
467 | fprintf( stdout, "registering service \"%s.%s.%s\" port %d text \"%s\"\n", name, type, domain, port, text ); | |
468 | ||
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" ); | |
472 | } | |
473 | else if( strcmp( argv[ i ], "-rps" ) == 0 ) | |
474 | { | |
475 | DNSHostRegistrationFlags hostFlags; | |
476 | ||
8e92c31c | 477 | // 'r'egister 'p'roxy 's'ervice <host> <ip> <name> <type> <domain> <port> <txt> |
c9b9ae52 A |
478 | |
479 | require_action_string( argc > ( i + 7 ), exit, err = kDNSBadParamErr, "missing arguments" ); | |
480 | ++i; | |
481 | host = argv[ i++ ]; | |
482 | ip = argv[ i++ ]; | |
483 | name = argv[ i++ ]; | |
484 | type = argv[ i++ ]; | |
485 | domain = argv[ i++ ]; | |
8e92c31c | 486 | port = (uint16_t) atoi( argv[ i++ ] ); |
c9b9ae52 A |
487 | text = argv[ i ]; |
488 | textSize = strlen( text ); | |
489 | if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) ) | |
490 | { | |
491 | domain = "local."; | |
492 | } | |
493 | ||
494 | sscanf( ip, "%u.%u.%u.%u", &b[ 0 ], &b[ 1 ], &b[ 2 ], &b[ 3 ] ); | |
8e92c31c A |
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 ]; | |
c9b9ae52 A |
500 | |
501 | fprintf( stdout, "registering proxy service \"%s.%s.%s\" port %d text \"%s\"\n", name, type, domain, port, text ); | |
502 | ||
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" ); | |
507 | ||
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" ); | |
511 | } | |
512 | else if( strcmp( argv[ i ], "-rnss" ) == 0 ) | |
513 | { | |
514 | // 'r'egister 'n'o 's'uch 's'ervice <name> <type> <domain> | |
515 | ||
516 | require_action_string( argc > ( i + 3 ), exit, err = kDNSBadParamErr, "missing arguments" ); | |
517 | ++i; | |
518 | name = argv[ i++ ]; | |
519 | type = argv[ i++ ]; | |
520 | domain = argv[ i++ ]; | |
521 | if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) ) | |
522 | { | |
523 | domain = "local."; | |
524 | } | |
525 | fprintf( stdout, "registering no-such-service \"%s.%s.%s\"\n", name, type, domain ); | |
526 | ||
527 | err = DNSNoSuchServiceRegistrationCreate( 0, name, type, domain, NULL, RegistrationCallBack, NULL, NULL ); | |
528 | require_noerr_string( err, exit, "create no-such-service registration failed" ); | |
529 | } | |
530 | else if( strcmp( argv[ i ], "-ebs" ) == 0 ) | |
531 | { | |
532 | // 'e'mulated 'b'rowse for 's'ervices <type> <domain> | |
533 | ||
534 | require_action_string( argc > ( i + 2 ), exit, err = kDNSBadParamErr, "missing arguments" ); | |
535 | ++i; | |
536 | type = argv[ i++ ]; | |
537 | domain = argv[ i ]; | |
538 | if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) ) | |
539 | { | |
540 | domain = "local."; | |
541 | } | |
542 | fprintf( stdout, "emulated browsing for \"%s.%s\"\n", type, domain ); | |
543 | ||
544 | emulatedRef = DNSServiceBrowserCreate( type, domain, EmulatedBrowserCallBack, NULL ); | |
545 | require_action_string( emulatedRef, exit, err = kDNSUnknownErr, "create emulated browser failed" ); | |
546 | } | |
547 | else if( strcmp( argv[ i ], "-ebd" ) == 0 ) | |
548 | { | |
549 | int registrationOnly; | |
550 | ||
551 | // 'e'mulated 'b'rowse for 'd'omains <registration/browse> | |
552 | ||
553 | require_action_string( argc > ( i + 1 ), exit, err = kDNSBadParamErr, "missing arguments" ); | |
554 | ++i; | |
555 | type = argv[ i++ ]; | |
556 | if( strcmp( type, "registration" ) == 0 ) | |
557 | { | |
558 | registrationOnly = 1; | |
559 | } | |
560 | else if( strcmp( type, "browse" ) == 0 ) | |
561 | { | |
562 | registrationOnly = 0; | |
563 | } | |
564 | else | |
565 | { | |
566 | require_action_string( 0, exit, err = kDNSBadParamErr, "invalid browse type" ); | |
567 | } | |
568 | fprintf( stdout, "emulated browsing for %s domains\n", type ); | |
569 | ||
570 | emulatedRef = DNSServiceDomainEnumerationCreate( registrationOnly, EmulatedDomainEnumerationCallBack, NULL ); | |
571 | require_action_string( emulatedRef, exit, err = kDNSUnknownErr, "create emulated domain browser failed" ); | |
572 | } | |
573 | else if( strcmp( argv[ i ], "-elsi" ) == 0 ) | |
574 | { | |
575 | // 'e'mulated 'l'ookup 's'ervice 'i'nstance <name> <type> <domain> | |
576 | ||
577 | require_action_string( argc > ( i + 3 ), exit, err = kDNSBadParamErr, "missing arguments" ); | |
578 | ++i; | |
579 | name = argv[ i++ ]; | |
580 | type = argv[ i++ ]; | |
581 | domain = argv[ i ]; | |
582 | if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) ) | |
583 | { | |
584 | domain = "local."; | |
585 | } | |
586 | fprintf( stdout, "emulated resolving \"%s.%s.%s\"\n", name, type, domain ); | |
587 | ||
588 | emulatedRef = DNSServiceResolverResolve( name, type, domain, EmulatedResolverCallBack, NULL ); | |
589 | require_action_string( emulatedRef, exit, err = kDNSUnknownErr, "create emulated resolver failed" ); | |
590 | } | |
591 | else if( strcmp( argv[ i ], "-ers" ) == 0 ) | |
592 | { | |
593 | // 'e'mulated 'r'egister 's'ervice <name> <type> <domain> <port> <txt> | |
594 | ||
595 | require_action_string( argc > ( i + 5 ), exit, err = kDNSBadParamErr, "missing arguments" ); | |
596 | ++i; | |
597 | name = argv[ i++ ]; | |
598 | type = argv[ i++ ]; | |
599 | domain = argv[ i++ ]; | |
8e92c31c | 600 | port = (uint16_t) atoi( argv[ i++ ] ); |
c9b9ae52 A |
601 | text = argv[ i ]; |
602 | textSize = strlen( text ); | |
8e92c31c | 603 | if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) ) |
c9b9ae52 A |
604 | { |
605 | domain = "local."; | |
606 | } | |
607 | fprintf( stdout, "registering service \"%s.%s.%s\" port %d text \"%s\"\n", name, type, domain, port, text ); | |
608 | ||
8e92c31c | 609 | emulatedRef = DNSServiceRegistrationCreate( name, type, domain, htons( port ), text, |
c9b9ae52 A |
610 | EmulatedRegistrationCallBack, NULL ); |
611 | require_action_string( emulatedRef, exit, err = kDNSUnknownErr, "create emulated registration failed" ); | |
612 | } | |
613 | else if( ( argv[ i ][ 0 ] == '-' ) && isdigit( argv[ i ][ 1 ] ) ) | |
614 | { | |
615 | // Preset | |
616 | ||
617 | ProcessPreset( atoi( &argv[ i ][ 1 ] ) ); | |
618 | err = 0; | |
619 | goto exit; | |
620 | } | |
621 | else if( strcmp( argv[ i ], "-q" ) == 0 ) | |
622 | { | |
623 | // Quiet (no text records) | |
624 | ||
625 | gPrintTXTRecords = 0; | |
626 | } | |
627 | else if( ( strcmp( argv[ i ], "-help" ) == 0 ) || ( strcmp( argv[ i ], "-h" ) == 0 ) ) | |
628 | { | |
629 | // Help | |
630 | ||
631 | Usage(); | |
632 | err = 0; | |
633 | goto exit; | |
634 | } | |
635 | else | |
636 | { | |
637 | // Unknown parameter. | |
638 | ||
639 | require_action_string( 0, exit, err = kDNSBadParamErr, "unknown parameter" ); | |
640 | goto exit; | |
641 | } | |
642 | } | |
643 | ||
644 | // Run until control-C'd. | |
645 | ||
646 | #if( __MACH__ ) | |
647 | CFRunLoopRun(); | |
648 | #endif | |
649 | ||
650 | #if( defined( WINVER ) ) | |
651 | while( !gQuit ) | |
652 | { | |
653 | Sleep( 200 ); | |
654 | } | |
655 | #endif | |
656 | ||
657 | err = kDNSNoErr; | |
658 | ||
659 | exit: | |
660 | if( err ) | |
661 | { | |
662 | Usage(); | |
663 | } | |
664 | return( err ); | |
665 | } | |
666 | ||
667 | //=========================================================================================================================== | |
668 | // ProcessPreset | |
669 | //=========================================================================================================================== | |
670 | ||
671 | static DNSStatus ProcessPreset( int inPreset ) | |
672 | { | |
673 | DNSStatus err; | |
674 | ||
675 | require_action_string( ( inPreset > 0 ) && ( inPreset <= gPresetsCount ), exit, err = kDNSBadParamErr, "invalid preset" ); | |
676 | ||
677 | err = ProcessArgs( gPresets[ inPreset - 1 ].argc, (char **) gPresets[ inPreset - 1 ].argv ); | |
678 | ||
679 | exit: | |
680 | return( err ); | |
681 | } | |
682 | ||
683 | #if( __MACH__ ) | |
684 | //=========================================================================================================================== | |
685 | // SigIntHandler | |
686 | //=========================================================================================================================== | |
687 | ||
688 | static void SigIntHandler( int inSignalNumber ) | |
689 | { | |
690 | DNS_UNUSED( inSignalNumber ); | |
691 | ||
692 | signal( SIGINT, SIG_DFL ); | |
693 | CFRunLoopStop( CFRunLoopGetCurrent() ); | |
694 | } | |
695 | #endif | |
696 | ||
697 | #if( defined( WINVER ) ) | |
698 | //=========================================================================================================================== | |
699 | // ConsoleControlHandler | |
700 | //=========================================================================================================================== | |
701 | ||
702 | static BOOL WINAPI ConsoleControlHandler( DWORD inControlEvent ) | |
703 | { | |
704 | BOOL handled; | |
705 | ||
706 | handled = 0; | |
707 | switch( inControlEvent ) | |
708 | { | |
709 | case CTRL_C_EVENT: | |
710 | case CTRL_BREAK_EVENT: | |
711 | case CTRL_CLOSE_EVENT: | |
712 | case CTRL_LOGOFF_EVENT: | |
713 | case CTRL_SHUTDOWN_EVENT: | |
714 | gQuit = 1; | |
715 | handled = 1; | |
716 | break; | |
717 | ||
718 | default: | |
719 | break; | |
720 | } | |
721 | return( handled ); | |
722 | } | |
723 | #endif | |
724 | ||
725 | //=========================================================================================================================== | |
726 | // BrowserCallBack | |
727 | //=========================================================================================================================== | |
728 | ||
729 | static void BrowserCallBack( void *inContext, DNSBrowserRef inRef, DNSStatus inStatusCode, const DNSBrowserEvent *inEvent ) | |
730 | { | |
731 | char ifIP[ 32 ]; | |
732 | char ip[ 32 ]; | |
733 | ||
734 | DNS_UNUSED( inContext ); | |
735 | DNS_UNUSED( inRef ); | |
736 | DNS_UNUSED( inStatusCode ); | |
737 | ||
738 | switch( inEvent->type ) | |
739 | { | |
740 | case kDNSBrowserEventTypeRelease: | |
741 | break; | |
742 | ||
743 | case kDNSBrowserEventTypeAddDomain: | |
7f0064bd | 744 | fprintf( stdout, "domain \"%s\" added on interface 0x%p (%s)\n", |
c9b9ae52 A |
745 | inEvent->data.addDomain.domain, |
746 | (int) inEvent->data.addDomain.interfaceID, | |
747 | IPv4ToString( inEvent->data.addDomain.interfaceIP.u.ipv4.addr, ifIP ) ); | |
748 | break; | |
749 | ||
750 | case kDNSBrowserEventTypeAddDefaultDomain: | |
7f0064bd | 751 | fprintf( stdout, "default domain \"%s\" added on interface 0x%p (%s)\n", |
c9b9ae52 A |
752 | inEvent->data.addDefaultDomain.domain, |
753 | (int) inEvent->data.addDefaultDomain.interfaceID, | |
754 | IPv4ToString( inEvent->data.addDefaultDomain.interfaceIP.u.ipv4.addr, ifIP ) ); | |
755 | break; | |
756 | ||
757 | case kDNSBrowserEventTypeRemoveDomain: | |
7f0064bd | 758 | fprintf( stdout, "domain \"%s\" removed on interface 0x%p (%s)\n", |
c9b9ae52 A |
759 | inEvent->data.removeDomain.domain, |
760 | (int) inEvent->data.removeDomain.interfaceID, | |
761 | IPv4ToString( inEvent->data.removeDomain.interfaceIP.u.ipv4.addr, ifIP ) ); | |
762 | break; | |
763 | ||
764 | case kDNSBrowserEventTypeAddService: | |
7f0064bd | 765 | fprintf( stdout, "service \"%s.%s%s\" added on interface 0x%p (%s)\n", |
c9b9ae52 A |
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 ) ); | |
771 | break; | |
772 | ||
773 | case kDNSBrowserEventTypeRemoveService: | |
7f0064bd | 774 | fprintf( stdout, "service \"%s.%s%s\" removed on interface 0x%p (%s)\n", |
c9b9ae52 A |
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 ) ); | |
780 | break; | |
781 | ||
782 | case kDNSBrowserEventTypeResolved: | |
783 | { | |
784 | const uint8_t * p; | |
785 | const uint8_t * end; | |
786 | int i; | |
787 | ||
7f0064bd | 788 | fprintf( stdout, "resolved \"%s.%s%s\" to \"%s\" (%s:%u) on interface 0x%p (%s)%s\n", |
c9b9ae52 A |
789 | inEvent->data.resolved->name, |
790 | inEvent->data.resolved->type, | |
791 | inEvent->data.resolved->domain, | |
8e92c31c | 792 | inEvent->data.resolved->hostName, |
c9b9ae52 A |
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:" : "" ); | |
799 | ||
800 | p = (const uint8_t *) inEvent->data.resolved->textRecordRaw; | |
801 | end = p + inEvent->data.resolved->textRecordRawSize; | |
802 | i = 0; | |
803 | ||
804 | if( gPrintTXTRecords ) | |
805 | { | |
806 | while( p < end ) | |
807 | { | |
808 | uint8_t size; | |
809 | ||
810 | size = *p++; | |
811 | if( ( p + size ) > end ) | |
812 | { | |
813 | fprintf( stdout, "\n### MALFORMED TXT RECORD (length byte too big for record)\n\n" ); | |
814 | break; | |
815 | } | |
816 | fprintf( stdout, "%5d (%3d bytes): \"%.*s\"\n", i, size, size, p ); | |
817 | p += size; | |
818 | ++i; | |
819 | } | |
820 | fprintf( stdout, "\n" ); | |
821 | } | |
822 | break; | |
823 | } | |
824 | ||
825 | default: | |
826 | break; | |
827 | } | |
828 | } | |
829 | ||
830 | //=========================================================================================================================== | |
831 | // ResolverCallBack | |
832 | //=========================================================================================================================== | |
833 | ||
834 | static void ResolverCallBack( void *inContext, DNSResolverRef inRef, DNSStatus inStatusCode, const DNSResolverEvent *inEvent ) | |
835 | { | |
836 | char ifIP[ 32 ]; | |
837 | char ip[ 32 ]; | |
838 | ||
839 | DNS_UNUSED( inContext ); | |
840 | DNS_UNUSED( inRef ); | |
841 | DNS_UNUSED( inStatusCode ); | |
842 | ||
843 | switch( inEvent->type ) | |
844 | { | |
845 | case kDNSResolverEventTypeResolved: | |
846 | { | |
847 | const uint8_t * p; | |
848 | const uint8_t * end; | |
849 | int i; | |
850 | ||
7f0064bd | 851 | fprintf( stdout, "resolved \"%s.%s%s\" to \"%s\" (%s:%u) on interface 0x%p (%s)%s\n", |
c9b9ae52 A |
852 | inEvent->data.resolved.name, |
853 | inEvent->data.resolved.type, | |
854 | inEvent->data.resolved.domain, | |
8e92c31c | 855 | inEvent->data.resolved.hostName, |
c9b9ae52 A |
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:" : "" ); | |
862 | ||
863 | p = (const uint8_t *) inEvent->data.resolved.textRecordRaw; | |
864 | end = p + inEvent->data.resolved.textRecordRawSize; | |
865 | i = 0; | |
866 | ||
867 | if( gPrintTXTRecords ) | |
868 | { | |
869 | while( p < end ) | |
870 | { | |
871 | uint8_t size; | |
872 | ||
873 | size = *p++; | |
874 | if( ( p + size ) > end ) | |
875 | { | |
876 | fprintf( stdout, "\n### MALFORMED TXT RECORD (length byte too big for record)\n\n" ); | |
877 | break; | |
878 | } | |
879 | fprintf( stdout, "%5d (%3d bytes): \"%.*s\"\n", i, size, size, p ); | |
880 | p += size; | |
881 | ++i; | |
882 | } | |
883 | fprintf( stdout, "\n" ); | |
884 | } | |
885 | break; | |
886 | } | |
887 | ||
888 | case kDNSResolverEventTypeRelease: | |
889 | break; | |
890 | ||
891 | default: | |
892 | break; | |
893 | } | |
894 | } | |
895 | ||
896 | //=========================================================================================================================== | |
897 | // RegistrationCallBack | |
898 | //=========================================================================================================================== | |
899 | ||
900 | static void | |
901 | RegistrationCallBack( | |
902 | void * inContext, | |
903 | DNSRegistrationRef inRef, | |
904 | DNSStatus inStatusCode, | |
905 | const DNSRegistrationEvent * inEvent ) | |
906 | { | |
907 | DNS_UNUSED( inContext ); | |
908 | DNS_UNUSED( inRef ); | |
909 | DNS_UNUSED( inStatusCode ); | |
910 | ||
911 | switch( inEvent->type ) | |
912 | { | |
913 | case kDNSRegistrationEventTypeRelease: | |
914 | break; | |
915 | ||
916 | case kDNSRegistrationEventTypeRegistered: | |
917 | fprintf( stdout, "name registered and active\n" ); | |
918 | break; | |
919 | ||
920 | case kDNSRegistrationEventTypeNameCollision: | |
921 | fprintf( stdout, "name in use, please choose another name\n" ); | |
922 | break; | |
923 | ||
924 | default: | |
925 | break; | |
926 | } | |
927 | } | |
928 | ||
929 | //=========================================================================================================================== | |
930 | // HostRegistrationCallBack | |
931 | //=========================================================================================================================== | |
932 | ||
933 | static void | |
934 | HostRegistrationCallBack( | |
935 | void * inContext, | |
936 | DNSHostRegistrationRef inRef, | |
937 | DNSStatus inStatusCode, | |
938 | void * inData ) | |
939 | { | |
940 | DNS_UNUSED( inContext ); | |
941 | DNS_UNUSED( inRef ); | |
942 | DNS_UNUSED( inData ); | |
943 | ||
944 | if( inStatusCode == kDNSNoErr ) | |
945 | { | |
946 | fprintf( stdout, "host name registered and active\n" ); | |
947 | } | |
948 | else if( inStatusCode == kDNSNameConflictErr ) | |
949 | { | |
950 | fprintf( stdout, "host name in use, please choose another name\n" ); | |
951 | } | |
952 | else | |
953 | { | |
954 | fprintf( stdout, "unknown host registration status (%ld)\n", inStatusCode ); | |
955 | } | |
956 | } | |
957 | ||
958 | //=========================================================================================================================== | |
959 | // EmulatedBrowserCallBack | |
960 | //=========================================================================================================================== | |
961 | ||
962 | static void | |
963 | EmulatedBrowserCallBack( | |
964 | DNSServiceBrowserReplyResultType inResult, | |
965 | const char * inName, | |
966 | const char * inType, | |
967 | const char * inDomain, | |
968 | DNSServiceDiscoveryReplyFlags inFlags, | |
969 | void * inContext ) | |
970 | { | |
971 | DNS_UNUSED( inFlags ); | |
972 | DNS_UNUSED( inContext ); | |
973 | ||
974 | if( inResult == DNSServiceBrowserReplyAddInstance ) | |
975 | { | |
976 | fprintf( stdout, "\"%s.%s%s\" service added emulated\n", inName, inType, inDomain ); | |
977 | } | |
978 | else if( inResult == DNSServiceBrowserReplyRemoveInstance ) | |
979 | { | |
980 | fprintf( stdout, "\"%s.%s%s\" service removed emulated\n", inName, inType, inDomain ); | |
981 | } | |
982 | else | |
983 | { | |
984 | fprintf( stdout, "### unknown emulated browser callback result (%d)\n", inResult ); | |
985 | } | |
986 | } | |
987 | ||
988 | //=========================================================================================================================== | |
989 | // EmulatedDomainEnumerationCallBack | |
990 | //=========================================================================================================================== | |
991 | ||
992 | static void | |
993 | EmulatedDomainEnumerationCallBack( | |
994 | DNSServiceDomainEnumerationReplyResultType inResult, | |
995 | const char * inDomain, | |
996 | DNSServiceDiscoveryReplyFlags inFlags, | |
997 | void * inContext ) | |
998 | { | |
999 | DNS_UNUSED( inFlags ); | |
1000 | DNS_UNUSED( inContext ); | |
1001 | ||
1002 | if( inResult == DNSServiceDomainEnumerationReplyAddDomain ) | |
1003 | { | |
1004 | fprintf( stdout, "\"%s\" domain added emulated\n", inDomain ); | |
1005 | } | |
1006 | else if( inResult == DNSServiceDomainEnumerationReplyAddDomainDefault ) | |
1007 | { | |
1008 | fprintf( stdout, "\"%s\" default domain added emulated\n", inDomain ); | |
1009 | } | |
1010 | else if( inResult == DNSServiceDomainEnumerationReplyRemoveDomain ) | |
1011 | { | |
1012 | fprintf( stdout, "\"%s\" domain removed emulated\n", inDomain ); | |
1013 | } | |
1014 | else | |
1015 | { | |
1016 | fprintf( stdout, "### unknown emulated domain enumeration callback result (%d)\n", inResult ); | |
1017 | } | |
1018 | } | |
1019 | ||
1020 | //=========================================================================================================================== | |
1021 | // EmulatedResolverCallBack | |
1022 | //=========================================================================================================================== | |
1023 | ||
1024 | static void | |
1025 | EmulatedResolverCallBack( | |
1026 | struct sockaddr * inInterfaceAddr, | |
1027 | struct sockaddr * inAddr, | |
1028 | const char * inTextRecord, | |
1029 | DNSServiceDiscoveryReplyFlags inFlags, | |
1030 | void * inContext ) | |
1031 | { | |
1032 | struct sockaddr_in * ifSin4; | |
1033 | struct sockaddr_in * sin4; | |
1034 | char ifIP[ 64 ]; | |
1035 | char ip[ 64 ]; | |
1036 | ||
1037 | DNS_UNUSED( inFlags ); | |
1038 | DNS_UNUSED( inContext ); | |
1039 | ||
1040 | ifSin4 = (struct sockaddr_in *) inInterfaceAddr; | |
1041 | sin4 = (struct sockaddr_in *) inAddr; | |
1042 | ||
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 : "" ); | |
1048 | } | |
1049 | ||
1050 | //=========================================================================================================================== | |
1051 | // EmulatedResolverCallBack | |
1052 | //=========================================================================================================================== | |
1053 | ||
1054 | static void EmulatedRegistrationCallBack( DNSServiceRegistrationReplyErrorType inResult, void *inContext ) | |
1055 | { | |
1056 | DNS_UNUSED( inContext ); | |
1057 | ||
1058 | if( inResult == kDNSServiceDiscoveryNoError ) | |
1059 | { | |
1060 | fprintf( stdout, "service name registered successfully\n" ); | |
1061 | } | |
1062 | else | |
1063 | { | |
1064 | fprintf( stdout, "service registration failed( %d)\n", inResult ); | |
1065 | } | |
1066 | } | |
1067 | ||
1068 | //=========================================================================================================================== | |
1069 | // IPv4ToString | |
1070 | //=========================================================================================================================== | |
1071 | ||
1072 | static char * IPv4ToString( DNSOpaque32 inIP, char *outString ) | |
1073 | { | |
1074 | sprintf( outString, "%u.%u.%u.%u", inIP.v8[ 0 ], inIP.v8[ 1 ], inIP.v8[ 2 ], inIP.v8[ 3 ] ); | |
1075 | return( outString ); | |
1076 | } |