Example #1
0
/*
 * rend_callback
 *
 * This gets called from the main thread when there is a
 * message waiting to be processed.
 */
void rend_callback(void *info) {
    REND_MESSAGE msg;
    unsigned short usPort;
    dns_service_discovery_ref dns_ref=NULL;

    /* here, we've seen the message, now we have to process it */
    if(rend_read_message(&msg) != sizeof(msg)) {
	DPRINTF(E_FATAL,L_REND,"Rendezvous socket closed (daap server crashed?)  Aborting.\n");
	exit(EXIT_FAILURE);
    }

    switch(msg.cmd) {
    case REND_MSG_TYPE_REGISTER:
	DPRINTF(E_DBG,L_REND,"Registering %s.%s (%d)\n",msg.type,msg.name,msg.port);
        usPort=htons(msg.port);
	dns_ref=DNSServiceRegistrationCreate(msg.name,msg.type,"",usPort,
					     "txtvers=1\001Database ID=bedabb1edeadbea7",rend_reply,nil);
	if(rend_addtorunloop(dns_ref)) {
	    DPRINTF(E_WARN,L_REND,"Add to runloop failed\n");
	    rend_send_response(-1);
	} else {
	    rend_send_response(0); /* success */
	}
	break;
    case REND_MSG_TYPE_UNREGISTER:
	DPRINTF(E_WARN,L_REND,"Unsupported function: UNREGISTER\n");
	rend_send_response(-1); /* error */
	break;
    case REND_MSG_TYPE_STOP:
	DPRINTF(E_DBG,L_REND,"Stopping mDNS\n");
	rend_send_response(0);
	rend_stoprunloop();
	break;
    case REND_MSG_TYPE_STATUS:
	DPRINTF(E_DBG,L_REND,"Status inquiry -- returning 0\n");
	rend_send_response(0); /* success */
	break;
    default:
	break;
    }
}
Example #2
0
static int ProcessArgs( int argc, char* argv[] )
{
    DNSStatus						err;
    int								i;
    const char *					name;
    const char *					type;
    const char *					domain;
    uint16_t						port;
    const char *					text;
    size_t							textSize;
    DNSBrowserRef					browser;
    DNSResolverFlags				resolverFlags;
    DNSDomainRegistrationType		domainType;
    const char *					label;
    const char *					host;
    const char *					ip;
    unsigned int					b[ 4 ];
    DNSNetworkAddress				addr;
    dns_service_discovery_ref		emulatedRef;

    // Parse the command line arguments (ignore first argument since it's just the program name).

    require_action_string( argc >= 2, exit, err = kDNSBadParamErr, "no arguments specified" );

    for( i = 1; i < argc; ++i )
    {
        if( strcmp( argv[ i ], "-bbd" ) == 0 )
        {
            // 'b'rowse for 'b'rowsing 'd'omains

            fprintf( stdout, "browsing for browsing domains\n" );

            err = DNSBrowserCreate( 0, BrowserCallBack, NULL, &browser );
            require_noerr_string( err, exit, "create browser failed" );

            err = DNSBrowserStartDomainSearch( browser, 0 );
            require_noerr_string( err, exit, "start domain search failed" );
        }
        else if( strcmp( argv[ i ], "-brd" ) == 0 )
        {
            // 'b'rowse for 'r'egistration 'd'omains

            fprintf( stdout, "browsing for registration domains\n" );

            err = DNSBrowserCreate( 0, BrowserCallBack, NULL, &browser );
            require_noerr_string( err, exit, "create browser failed" );

            err = DNSBrowserStartDomainSearch( browser, kDNSBrowserFlagRegistrationDomainsOnly );
            require_noerr_string( err, exit, "start domain search failed" );
        }
        else if( strcmp( argv[ i ], "-bs" ) == 0 )
        {
            // 'b'rowse for 's'ervices <type> <domain>

            require_action_string( argc > ( i + 2 ), exit, err = kDNSBadParamErr, "missing arguments" );
            ++i;
            type 	= argv[ i++ ];
            domain 	= argv[ i ];
            if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
            {
                domain = "local.";
            }
            fprintf( stdout, "browsing for \"%s.%s\"\n", type, domain );

            err = DNSBrowserCreate( 0, BrowserCallBack, NULL, &browser );
            require_noerr_string( err, exit, "create browser failed" );

            err = DNSBrowserStartServiceSearch( browser, kDNSBrowserFlagAutoResolve, type, domain );
            require_noerr_string( err, exit, "start service search failed" );
        }
        else if( strcmp( argv[ i ], "-lsi" ) == 0 )
        {
            // 'l'ookup 's'ervice 'i'nstance <name> <type> <domain>

            require_action_string( argc > ( i + 3 ), exit, err = kDNSBadParamErr, "missing arguments" );
            ++i;
            name 	= argv[ i++ ];
            type 	= argv[ i++ ];
            domain 	= argv[ i ];
            if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
            {
                domain = "local.";
            }
            fprintf( stdout, "resolving \"%s.%s.%s\"\n", name, type, domain );

            resolverFlags = kDNSResolverFlagOnlyIfUnique |
                            kDNSResolverFlagAutoReleaseByName;
            err = DNSResolverCreate( resolverFlags, name, type, domain, ResolverCallBack, 0, NULL, NULL );
            require_noerr_string( err, exit, "create resolver failed" );
        }
        else if( ( strcmp( argv[ i ], "-rdb" ) == 0 ) || ( strcmp( argv[ i ], "-rdbd" ) == 0 ) )
        {
            // 'r'egister 'd'omain for 'b'rowsing ['d'efault] <domain>

            require_action_string( argc > ( i + 1 ), exit, err = kDNSBadParamErr, "missing arguments" );
            if( strcmp( argv[ i ], "-rdb" ) == 0 )
            {
                domainType = kDNSDomainRegistrationTypeBrowse;
                label = "";
            }
            else
            {
                domainType = kDNSDomainRegistrationTypeBrowseDefault;
                label = "default ";
            }
            ++i;
            domain = argv[ i ];
            if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
            {
                domain = "local.";
            }
            fprintf( stdout, "registering \"%s\" as %sbrowse domain\n", domain, label );

            err = DNSDomainRegistrationCreate( 0, domain, domainType, NULL );
            require_noerr_string( err, exit, "create domain registration failed" );
        }
        else if( ( strcmp( argv[ i ], "-rdr" ) == 0 ) || ( strcmp( argv[ i ], "-rdrd" ) == 0 ) )
        {
            // 'r'egister 'd'omain for 'r'egistration ['d'efault] <domain>

            require_action_string( argc > ( i + 1 ), exit, err = kDNSBadParamErr, "missing arguments" );
            if( strcmp( argv[ i ], "-rdr" ) == 0 )
            {
                domainType = kDNSDomainRegistrationTypeRegistration;
                label = "";
            }
            else
            {
                domainType = kDNSDomainRegistrationTypeRegistrationDefault;
                label = "default ";
            }
            ++i;
            domain = argv[ i ];
            if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
            {
                domain = "local.";
            }
            fprintf( stdout, "registering \"%s\" as %sregistration domain\n", domain, label );

            err = DNSDomainRegistrationCreate( 0, domain, domainType, NULL );
            require_noerr_string( err, exit, "create domain registration failed" );
        }
        else if( strcmp( argv[ i ], "-rs" ) == 0 )
        {
            // 'r'egister 's'ervice <name> <type> <domain> <port> <txt>

            require_action_string( argc > ( i + 5 ), exit, err = kDNSBadParamErr, "missing arguments" );
            ++i;
            name 		= argv[ i++ ];
            type 		= argv[ i++ ];
            domain	 	= argv[ i++ ];
            port 		= (uint16_t) atoi( argv[ i++ ] );
            text 		= argv[ i ];
            textSize	= strlen( text );
            if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
            {
                domain = "local.";
            }
            fprintf( stdout, "registering service \"%s.%s.%s\" port %d text \"%s\"\n", name, type, domain, port, text );

            err = DNSRegistrationCreate( 0, name, type, domain, (DNSPort) port, text, (DNSCount) textSize, NULL, NULL,
                                         RegistrationCallBack, NULL, NULL );
            require_noerr_string( err, exit, "create registration failed" );
        }
        else if( strcmp( argv[ i ], "-rps" ) == 0 )
        {
            DNSHostRegistrationFlags		hostFlags;

            // 'r'egister 'p'roxy 's'ervice <host> <ip> <name> <type> <domain> <port> <txt>

            require_action_string( argc > ( i + 7 ), exit, err = kDNSBadParamErr, "missing arguments" );
            ++i;
            host		= argv[ i++ ];
            ip			= argv[ i++ ];
            name 		= argv[ i++ ];
            type 		= argv[ i++ ];
            domain	 	= argv[ i++ ];
            port 		= (uint16_t) atoi( argv[ i++ ] );
            text 		= argv[ i ];
            textSize	= strlen( text );
            if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
            {
                domain = "local.";
            }

            sscanf( ip, "%u.%u.%u.%u", &b[ 0 ], &b[ 1 ], &b[ 2 ], &b[ 3 ] );
            addr.addressType 			= kDNSNetworkAddressTypeIPv4;
            addr.u.ipv4.addr.v8[ 0 ] 	= (DNSUInt8) b[ 0 ];
            addr.u.ipv4.addr.v8[ 1 ] 	= (DNSUInt8) b[ 1 ];
            addr.u.ipv4.addr.v8[ 2 ] 	= (DNSUInt8) b[ 2 ];
            addr.u.ipv4.addr.v8[ 3 ] 	= (DNSUInt8) b[ 3 ];

            fprintf( stdout, "registering proxy service \"%s.%s.%s\" port %d text \"%s\"\n", name, type, domain, port, text );

            hostFlags = kDNSHostRegistrationFlagOnlyIfNotFound | kDNSHostRegistrationFlagAutoRenameOnConflict;
            err = DNSHostRegistrationCreate( hostFlags, host, domain, &addr, NULL,
                                             HostRegistrationCallBack, NULL, NULL );
            require_noerr_string( err, exit, "create host registration failed" );

            err = DNSRegistrationCreate( 0, name, type, domain, (DNSPort) port, text, (DNSCount) textSize, host, NULL,
                                         RegistrationCallBack, NULL, NULL );
            require_noerr_string( err, exit, "create registration failed" );
        }
        else if( strcmp( argv[ i ], "-rnss" ) == 0 )
        {
            // 'r'egister 'n'o 's'uch 's'ervice <name> <type> <domain>

            require_action_string( argc > ( i + 3 ), exit, err = kDNSBadParamErr, "missing arguments" );
            ++i;
            name 		= argv[ i++ ];
            type 		= argv[ i++ ];
            domain	 	= argv[ i++ ];
            if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
            {
                domain = "local.";
            }
            fprintf( stdout, "registering no-such-service \"%s.%s.%s\"\n", name, type, domain );

            err = DNSNoSuchServiceRegistrationCreate( 0, name, type, domain, NULL, RegistrationCallBack, NULL, NULL );
            require_noerr_string( err, exit, "create no-such-service registration failed" );
        }
        else if( strcmp( argv[ i ], "-ebs" ) == 0 )
        {
            // 'e'mulated 'b'rowse for 's'ervices <type> <domain>

            require_action_string( argc > ( i + 2 ), exit, err = kDNSBadParamErr, "missing arguments" );
            ++i;
            type 	= argv[ i++ ];
            domain 	= argv[ i ];
            if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
            {
                domain = "local.";
            }
            fprintf( stdout, "emulated browsing for \"%s.%s\"\n", type, domain );

            emulatedRef = DNSServiceBrowserCreate( type, domain, EmulatedBrowserCallBack, NULL );
            require_action_string( emulatedRef, exit, err = kDNSUnknownErr, "create emulated browser failed" );
        }
        else if( strcmp( argv[ i ], "-ebd" ) == 0 )
        {
            int		registrationOnly;

            // 'e'mulated 'b'rowse for 'd'omains <registration/browse>

            require_action_string( argc > ( i + 1 ), exit, err = kDNSBadParamErr, "missing arguments" );
            ++i;
            type = argv[ i++ ];
            if( strcmp( type, "registration" ) == 0 )
            {
                registrationOnly = 1;
            }
            else if( strcmp( type, "browse" ) == 0 )
            {
                registrationOnly = 0;
            }
            else
            {
                require_action_string( 0, exit, err = kDNSBadParamErr, "invalid browse type" );
            }
            fprintf( stdout, "emulated browsing for %s domains\n", type );

            emulatedRef = DNSServiceDomainEnumerationCreate( registrationOnly, EmulatedDomainEnumerationCallBack, NULL );
            require_action_string( emulatedRef, exit, err = kDNSUnknownErr, "create emulated domain browser failed" );
        }
        else if( strcmp( argv[ i ], "-elsi" ) == 0 )
        {
            // 'e'mulated 'l'ookup 's'ervice 'i'nstance <name> <type> <domain>

            require_action_string( argc > ( i + 3 ), exit, err = kDNSBadParamErr, "missing arguments" );
            ++i;
            name 	= argv[ i++ ];
            type 	= argv[ i++ ];
            domain 	= argv[ i ];
            if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
            {
                domain = "local.";
            }
            fprintf( stdout, "emulated resolving \"%s.%s.%s\"\n", name, type, domain );

            emulatedRef = DNSServiceResolverResolve( name, type, domain, EmulatedResolverCallBack, NULL );
            require_action_string( emulatedRef, exit, err = kDNSUnknownErr, "create emulated resolver failed" );
        }
        else if( strcmp( argv[ i ], "-ers" ) == 0 )
        {
            // 'e'mulated 'r'egister 's'ervice <name> <type> <domain> <port> <txt>

            require_action_string( argc > ( i + 5 ), exit, err = kDNSBadParamErr, "missing arguments" );
            ++i;
            name 		= argv[ i++ ];
            type 		= argv[ i++ ];
            domain	 	= argv[ i++ ];
            port 		= (uint16_t) atoi( argv[ i++ ] );
            text 		= argv[ i ];
            textSize	= strlen( text );
            if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
            {
                domain = "local.";
            }
            fprintf( stdout, "registering service \"%s.%s.%s\" port %d text \"%s\"\n", name, type, domain, port, text );

            emulatedRef = DNSServiceRegistrationCreate( name, type, domain, htons( port ), text,
                          EmulatedRegistrationCallBack, NULL );
            require_action_string( emulatedRef, exit, err = kDNSUnknownErr, "create emulated registration failed" );
        }
        else if( ( argv[ i ][ 0 ] == '-' ) && isdigit( argv[ i ][ 1 ] ) )
        {
            // Preset

            ProcessPreset( atoi( &argv[ i ][ 1 ] ) );
            err = 0;
            goto exit;
        }
        else if( strcmp( argv[ i ], "-q" ) == 0 )
        {
            // Quiet (no text records)

            gPrintTXTRecords = 0;
        }
        else if( ( strcmp( argv[ i ], "-help" ) == 0 ) || ( strcmp( argv[ i ], "-h" ) == 0 ) )
        {
            // Help

            Usage();
            err = 0;
            goto exit;
        }
        else
        {
            // Unknown parameter.

            require_action_string( 0, exit, err = kDNSBadParamErr, "unknown parameter" );
            goto exit;
        }
    }

    // Run until control-C'd.

#if( __MACH__ )
    CFRunLoopRun();
#endif

#if( defined( WINVER ) )
    while( !gQuit )
    {
        Sleep( 200 );
    }
#endif

    err = kDNSNoErr;

exit:
    if( err )
    {
        Usage();
    }
    return( err );
}