Beispiel #1
0
void start_remote_debug_server(AMDeviceRef device) {
    assert(AMDeviceStartService(device, CFSTR("com.apple.debugserver"), &gdbfd, NULL) == 0);

    CFSocketRef fdvendor = CFSocketCreate(NULL, AF_UNIX, 0, 0, kCFSocketAcceptCallBack, &fdvendor_callback, NULL);

    int yes = 1;
    setsockopt(CFSocketGetNative(fdvendor), SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));

    struct sockaddr_un address;
    memset(&address, 0, sizeof(address));
    address.sun_family = AF_UNIX;
    strcpy(address.sun_path, FDVENDOR_PATH);
    CFDataRef address_data = CFDataCreate(NULL, (const UInt8 *)&address, sizeof(address));

    unlink(FDVENDOR_PATH);

    CFSocketSetAddress(fdvendor, address_data);
    CFRelease(address_data);
    CFRunLoopAddSource(CFRunLoopGetMain(), CFSocketCreateRunLoopSource(NULL, fdvendor, 0), kCFRunLoopCommonModes);
}
Beispiel #2
0
void StartDebuggingAndDetach(char *udid, char *app_path) {
	SDMMD_AMDeviceRef device = FindDeviceFromUDID(udid);
	if (device) {

		CFStringRef bundleId = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)app_path, strlen(app_path), kCFStringEncodingUTF8, false);
		CFURLRef relative_url = CFURLCreateWithFileSystemPath(NULL, bundleId, kCFURLPOSIXPathStyle, false);
		CFURLRef disk_app_url = CFURLCopyAbsoluteURL(relative_url);
		CFStringRef bundle_identifier = copy_disk_app_identifier(disk_app_url);

		
		SDMMD_AMDebugConnectionRef debug = SDMMD_AMDebugConnectionCreateForDevice(device);
		SDMMD_AMDebugConnectionStart(debug);
		
		uintptr_t socket = SDMMD_AMDServiceConnectionGetSocket(debug->connection);
		CFSocketContext context = { 0, (void*)socket, NULL, NULL, NULL };
		CFSocketRef fdvendor = CFSocketCreate(NULL, AF_UNIX, 0, 0, kCFSocketAcceptCallBack, &socket_callback, &context);
		
		int yes = 1;
		setsockopt(CFSocketGetNative(fdvendor), SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
		
		struct sockaddr_un address;
		memset(&address, 0, sizeof(address));
		address.sun_family = AF_UNIX;
		strcpy(address.sun_path, SDM_LLDB_SOCKET);
		address.sun_len = SUN_LEN(&address);
		CFDataRef address_data = CFDataCreate(NULL, (const UInt8 *)&address, sizeof(address));
		
		unlink(SDM_LLDB_SOCKET);
		
		CFSocketSetAddress(fdvendor, address_data);
		CFRelease(address_data);
		CFRunLoopAddSource(CFRunLoopGetMain(), CFSocketCreateRunLoopSource(NULL, fdvendor, 0), kCFRunLoopCommonModes);
		
		SDMMD_AMDeviceRef device = SDMMD_AMDServiceConnectionGetDevice(debug->connection);
		CFMutableStringRef cmds = CFStringCreateMutableCopy(NULL, 0, LLDB_PREP_CMDS);
		CFRange range = { 0, CFStringGetLength(cmds) };
		
		CFURLRef device_app_url = copy_device_app_url(device, bundle_identifier);
		CFStringRef device_app_path = CFURLCopyFileSystemPath(device_app_url, kCFURLPOSIXPathStyle);
		CFStringFindAndReplace(cmds, CFSTR("{DEVICE_PATH}"), device_app_path, range, 0);
		range.length = CFStringGetLength(cmds);
		
		CFStringRef disk_app_path = CFURLCopyFileSystemPath(disk_app_url, kCFURLPOSIXPathStyle);
		CFStringFindAndReplace(cmds, CFSTR("{APP_PATH}"), disk_app_path, range, 0);
		range.length = CFStringGetLength(cmds);
		
		CFURLRef device_container_url = CFURLCreateCopyDeletingLastPathComponent(NULL, device_app_url);
		CFStringRef device_container_path = CFURLCopyFileSystemPath(device_container_url, kCFURLPOSIXPathStyle);
		CFMutableStringRef dcp_noprivate = CFStringCreateMutableCopy(NULL, 0, device_container_path);
		range.length = CFStringGetLength(dcp_noprivate);
		CFStringFindAndReplace(dcp_noprivate, CFSTR("/private/var/"), CFSTR("/var/"), range, 0);
		range.length = CFStringGetLength(cmds);
		CFStringFindAndReplace(cmds, CFSTR("{device_container}"), dcp_noprivate, range, 0);
		range.length = CFStringGetLength(cmds);
		
		CFURLRef disk_container_url = CFURLCreateCopyDeletingLastPathComponent(NULL, disk_app_url);
		CFStringRef disk_container_path = CFURLCopyFileSystemPath(disk_container_url, kCFURLPOSIXPathStyle);
		CFStringFindAndReplace(cmds, CFSTR("{disk_container}"), disk_container_path, range, 0);
		
		CFDataRef cmds_data = CFStringCreateExternalRepresentation(NULL, cmds, kCFStringEncodingASCII, 0);
		FILE *out = fopen(PREP_CMDS_PATH, "w");
		fwrite(CFDataGetBytePtr(cmds_data), CFDataGetLength(cmds_data), 1, out);
		fclose(out);
		
		CFSafeRelease(cmds);
		CFSafeRelease(bundle_identifier);
		CFSafeRelease(device_app_url);
		CFSafeRelease(device_app_path);
		CFSafeRelease(disk_app_path);
		CFSafeRelease(device_container_url);
		CFSafeRelease(device_container_path);
		CFSafeRelease(dcp_noprivate);
		CFSafeRelease(disk_container_url);
		CFSafeRelease(disk_container_path);
		CFSafeRelease(cmds_data);
		
		signal(SIGHUP, exit);
		
		pid_t parent = getpid();
		int pid = fork();
		if (pid == 0) {
			system("xcrun -sdk iphoneos lldb /tmp/sdmmd-lldb-prep");
			kill(parent, SIGHUP);
			_exit(0);
		}
		CFRunLoopRun();
	}
}
Beispiel #3
0
/* extern */ _CFServerRef
_CFServerCreate(CFAllocatorRef alloc, _CFServerCallBack callback, _CFServerContext* context) {
    
    Server* server = NULL;
	    
	do {
		int yes = 1;
		CFSocketContext socketCtxt = {0,
									  NULL,
									  (const void*(*)(const void*))&CFRetain,
									  (void(*)(const void*))&CFRelease,
									  (CFStringRef(*)(const void *))&CFCopyDescription};
        
        CFTypeID id = _CFServerGetTypeID();
    
        // Ask CF to allocate the instance and then return it.
        if (id != _kCFRuntimeNotATypeID) {
            server = (Server*)_CFRuntimeCreateInstance(alloc,
                                                       id,
                                                       sizeof(Server) - sizeof(CFRuntimeBase),
                                                       NULL);
        }
		
		// Fail if unable to create the server
		if (server == NULL)
			break;

        server->_name = NULL;
        server->_type = NULL;
        server->_port = 0;
        server->_service = NULL;
        memset(&server->_callback, 0, sizeof(server->_callback));
        memset(&server->_ctxt, 0, sizeof(server->_ctxt));
        
		// Make sure the server is saved for the callback.
		socketCtxt.info = server;
		
		// Create the IPv4 server socket.
		server->_sockets[0] = CFSocketCreate(alloc,
											 PF_INET,
											 SOCK_STREAM,
											 IPPROTO_TCP,
											 kCFSocketAcceptCallBack,
											 (CFSocketCallBack)&_SocketCallBack,
											 &socketCtxt);
		
		// If the socket couldn't create, bail.
		if (server->_sockets[0] == NULL)
			break;
		
		// Create the IPv6 server socket.
		server->_sockets[1] = CFSocketCreate(alloc,
											 PF_INET6,
											 SOCK_STREAM,
											 IPPROTO_TCP,
											 kCFSocketAcceptCallBack,
											 (CFSocketCallBack)&_SocketCallBack,
											 &socketCtxt);
		
		// If the socket couldn't create, bail.
		if (server->_sockets[1] == NULL)
			break;
		
		// In order to accomadate stopping and starting the process without closing the socket,
		// set the addr for resuse on the native socket.  This is not required if the port is
		// being supplied by the OS opposed to being specified by the user.
		setsockopt(CFSocketGetNative(server->_sockets[0]), SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(yes));
		setsockopt(CFSocketGetNative(server->_sockets[1]), SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(yes));
        
		// Save the user's callback in context.
		server->_callback = callback;
		memcpy(&(server->_ctxt), context, sizeof(server->_ctxt));
		
		// If there is info and a retain function, retain the info.
		if (server->_ctxt.info && server->_ctxt.retain)
			server->_ctxt.info = (void*)server->_ctxt.retain(server->_ctxt.info);
		
		return (_CFServerRef)server;
			
	} while (0);
	
	// Something failed, so clean up.
	if (server) {
		_CFServerInvalidate((_CFServerRef)server);
		CFRelease((_CFServerRef)server);
	}

    return NULL;
}
Beispiel #4
0
WebSocketRef
WebSocketCreateWithHostAndPort (CFAllocatorRef allocator, CFStringRef host, UInt16 port, void *userInfo) {
    WebSocketRef self = CFAllocatorAllocate(allocator, sizeof(WebSocket), 0);
    if (self) {
        self->allocator = allocator ? CFRetain(allocator) : NULL;
        self->retainCount = 1;
        self->userInfo = userInfo;

        self->clientsLength = 1024;
        self->clientsUsedLength = 0;
        if (NULL == (self->clients = CFAllocatorAllocate(allocator, self->clientsLength, 0))) {
            WebSocketRelease(self), self = NULL;
            goto fin;
        }

        // Callbacks
        self->callbacks.didAddClientCallback     = NULL;
        self->callbacks.willRemoveClientCallback = NULL;
        self->callbacks.didClientReadCallback    = NULL;

        // Setup the context;
        CFSocketContext context = {
            .copyDescription = NULL,
            .retain = NULL,
            .release = NULL,
            .version = 0,
            .info = self
        };

        if (NULL == (self->socket = CFSocketCreate(self->allocator, PF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketAcceptCallBack, __WebSocketAcceptCallBack, &context))) {
            WebSocketRelease(self), self = NULL;
            goto fin;
        }

        // Re-use local addresses, if they're still in TIME_WAIT
        int yes = 1;
        setsockopt(CFSocketGetNative(self->socket), SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes));

        // Set the port and address we want to listen on
        memset(&self->addr, 0, sizeof(self->addr));
        self->addr.sin_len = sizeof(self->addr);
        self->addr.sin_family = AF_INET;

        if (CFEqual(kWebSocketHostAny, host)) {

            // Host is set to "0.0.0.0", set it to INADDR_ANY
            self->addr.sin_addr.s_addr = htonl(INADDR_ANY);
        } else {

            // Set the host based on provided string. TODO: hostname resolution?
            CFIndex hostCStringLength = CFStringGetMaximumSizeForEncoding(CFStringGetLength(host), kCFStringEncodingASCII) + 1;
            char *hostCString = CFAllocatorAllocate(self->allocator, hostCStringLength, 0);
            if (hostCString) {
                if (CFStringGetCString(host, hostCString, hostCStringLength, kCFStringEncodingASCII)) {
                    inet_aton(hostCString, &self->addr.sin_addr);
                } else {

                    // TODO: Couldn't get CString
                }
                CFAllocatorDeallocate(self->allocator, hostCString);
            } else {

                // TODO: Couldn't allocate buffer
            }
        }

        self->addr.sin_port = htons(port);

        CFDataRef address = CFDataCreate(self->allocator, (const void *) &self->addr, sizeof(self->addr));
        if (address) {
            if (CFSocketSetAddress(self->socket, (CFDataRef) address) != kCFSocketSuccess) {
                WebSocketRelease(self), self = NULL;
                CFRelease(address);
                goto fin;
            }
            CFRelease(address);
        }

        // Create run loop source and add it to the current run loop
        CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(self->allocator, self->socket, 0);
        CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes);
        CFRelease(source);
    }

fin:

    return self;
}

WebSocketRef
WebSocketCreate (CFAllocatorRef allocator, void *userInfo) {
    return WebSocketCreateWithHostAndPort(allocator, kWebSocketHostLoopBack, kWebSocketPortAny, userInfo);
}

void
WebSocketRetain (WebSocketRef self) {
    if_self {
        ++self->retainCount;
    }
}
Beispiel #5
0
bool 
pSendUnitDeviceChangeNotification(
								  CFUUIDBytes pHostGuid,
								  PNDAS_HIX_UNITDEVICE_CHANGE_NOTIFY	data
								  )
{
	CFDataRef							cfdRequest = NULL;
	
	// Build Request.
	pBuildNHIXHeader(
					 &data->Header,
					 pHostGuid,
					 0,
					 NHIX_TYPE_UNITDEVICE_CHANGE,
					 sizeof(NDAS_HIX_UNITDEVICE_CHANGE_NOTIFY)
					 );
	
	cfdRequest = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (UInt8 *) data, sizeof(NDAS_HIX_UNITDEVICE_CHANGE_NOTIFY), kCFAllocatorNull);
	
	// Send Request.
	// Per Interface.
	
	CFSocketRef				sockets[16];
	int						numInterfaces = 0;

	for(int i = 0; i < numberOfNics; i++) {
	
		CFDataRef	address = 0;
		struct sockaddr_lpx	addr = { 0 };
		
		// Build Socket.
		sockets[numInterfaces] = CFSocketCreate (
												 kCFAllocatorDefault,
												 PF_LPX,
												 SOCK_DGRAM,
												 0,
												 0,
												 0,
												 NULL
												 );
		if(sockets[numInterfaces] == NULL) {
			syslog(LOG_ERR, "pSendSurrenderAccess: Can't Create socket for surrender Access request.");
			
			return false;
		}
		
		// Bind Interface Address.
		addr.slpx_family = AF_LPX;
		addr.slpx_len = sizeof(struct sockaddr_lpx);
		addr.slpx_port = 0;
		memcpy(addr.slpx_node, ethernetData[i].macAddress, 6);
		
		address = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, 
											  (UInt8 *) &addr, 
											  sizeof(struct sockaddr_lpx), 
											  kCFAllocatorNull);
		
		CFSocketError socketError = CFSocketSetAddress (
														sockets[numInterfaces],
														address
														);
		if(socketError != kCFSocketSuccess) {
			syslog(LOG_ERR, "pSendSurrenderAccess: Can't Bind.");
			continue;
		}
		
		if(address)		CFRelease(address);		address= NULL;
		
		// Create Broadcast address.
		addr.slpx_family = AF_LPX;
		addr.slpx_len = sizeof(struct sockaddr_lpx);
		memset(addr.slpx_node, 0xff, 6);
		addr.slpx_port = htons(NDAS_HIX_LISTEN_PORT);
		
		address = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, 
											  (UInt8 *) &addr, 
											  sizeof(struct sockaddr_lpx), 
											  kCFAllocatorNull);
		
		// Set Broadcast Flag.
		int on = 1;
		if(setsockopt(CFSocketGetNative(sockets[numInterfaces]), SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) != 0) {
			syslog(LOG_ERR, "pSendSurrenderAccess: Error when set option.");
			return false;
		}
		
		// Send Request.
		socketError = CFSocketSendData (
										sockets[numInterfaces],
										address,
										cfdRequest,
										0
										);
		
		if(socketError != kCFSocketSuccess) {
			syslog(LOG_ERR, "pSendSurrenderAccess: Error when send reply.");
			return false;
		}
		
		numInterfaces++;
		
		if(address)		CFRelease(address);
		
	}
	
	if(cfdRequest)	CFRelease(cfdRequest);
	
	return true;
}
Beispiel #6
0
bool 
pSendSurrenderAccess(
					 CFUUIDBytes pHostGuid,
					 PNDAS_HIX_UNITDEVICE_ENTRY_DATA	data,
					 struct  sockaddr_lpx				*hostAddr
					 )
{
	NDAS_HIX_SURRENDER_ACCESS_REQUEST	request;
	CFDataRef							cfdRequest = NULL;
		
	// Build Request.
	pBuildNHIXHeader(
					 &request.Header,
					 pHostGuid,
					 0,
					 NHIX_TYPE_SURRENDER_ACCESS,
					 sizeof(NDAS_HIX_SURRENDER_ACCESS_REQUEST)
					 );
	
	request.Data.EntryCount = 1;
	
	memcpy(&request.Data.Entry[0], data, sizeof(NDAS_HIX_UNITDEVICE_ENTRY_DATA));

	cfdRequest = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (UInt8 *) &request, sizeof(NDAS_HIX_SURRENDER_ACCESS_REQUEST), kCFAllocatorNull);

	// Send Request.
	// Per Interface.

	CFSocketRef				sockets[4];
	int						numInterfaces = 0;

	for(int i = 0; i < numberOfNics; i++) {
		
		CFDataRef	address = 0;
		struct sockaddr_lpx	addr = { 0 };
				
		// Build Socket.
		sockets[numInterfaces] = CFSocketCreate (
												 kCFAllocatorDefault,
												 PF_LPX,
												 SOCK_DGRAM,
												 0,
												 0,
												 0,
												 NULL
												 );
		if(sockets[numInterfaces] == NULL) {
			syslog(LOG_ERR, "pSendSurrenderAccess: Can't Create socket for surrender Access request.");
			
			return false;
		}
		
		// Bind Interface Address.
		addr.slpx_family = AF_LPX;
		addr.slpx_len = sizeof(struct sockaddr_lpx);
		addr.slpx_port = 0;
		memcpy(addr.slpx_node, ethernetData[i].macAddress, 6);
		
		address = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, 
											  (UInt8 *) &addr, 
											  sizeof(struct sockaddr_lpx), 
											  kCFAllocatorNull);
		
		CFSocketError socketError = CFSocketSetAddress (
														sockets[numInterfaces],
														address
														);
		if(socketError != kCFSocketSuccess) {
			syslog(LOG_ERR, "pSendSurrenderAccess: Can't Bind.");
			continue;
		}
		
		if(address)		CFRelease(address);		address= NULL;
		
		// Bind Peer Host Address.				
		address = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, 
											  (UInt8 *) hostAddr, 
											  sizeof(struct sockaddr_lpx), 
											  kCFAllocatorNull);
		
		// Send Request.
		socketError = CFSocketSendData (
										sockets[numInterfaces],
										address,
										cfdRequest,
										0
										);
		
		if(socketError != kCFSocketSuccess) {
			syslog(LOG_ERR, "pSendSurrenderAccess: Error when send reply.");
			return false;
		}
		
		numInterfaces++;
		
		if(address)		CFRelease(address);
		
	}
		
	if(cfdRequest)	CFRelease(cfdRequest);
	
	// Receive Reply.
	int			maxfdp1;
	socklen_t			fromlen;
	fd_set	rset;
	struct timeval timeout;
	bool	bResult;
	struct sockaddr_lpx	addr;
	int count;
	
	FD_ZERO(&rset);
	
	maxfdp1 = 0;
	for(count = 0; count < numInterfaces; count++) {
		FD_SET( CFSocketGetNative(sockets[count]), &rset);
		maxfdp1 = (maxfdp1 > CFSocketGetNative(sockets[count])) ? maxfdp1 : CFSocketGetNative(sockets[count]);	
	}
	maxfdp1++;
	
	timeout.tv_sec = 20;	// 20 sec.
	timeout.tv_usec = 0;
	
	int result = select(maxfdp1, &rset, NULL, NULL, &timeout);
	if(result > 0) {
		NDAS_HIX_SURRENDER_ACCESS_REPLY	reply;
		
		for(count = 0; count < numInterfaces; count++) {
			if (FD_ISSET( CFSocketGetNative(sockets[count]), &rset)) {
				
				int len;
				
				len = recvfrom(CFSocketGetNative(sockets[count]), &reply, sizeof(NDAS_HIX_SURRENDER_ACCESS_REPLY), 0, (sockaddr *)&addr, &fromlen);

				if(reply.Data.Status == NHIX_SURRENDER_REPLY_STATUS_QUEUED) {
					bResult = true;
				} else {
					bResult = false;
				}
			}
		}
	} else {
		// Error or timeout.
		syslog(LOG_ERR, "pSendSurrenderAccess: select error or timeout %d\n", result);
		
		bResult =  false;
	}
	
	//if(socketSurrender) CFRelease(socketSurrender);     
	for(count = 0; count < numInterfaces; count++) {
		if(sockets[count]) CFRelease(sockets[count]);	
	}
	
	return bResult;
}
Beispiel #7
0
int 
pSendDiscover(
			  CFUUIDBytes pHostGuid,
			  PNDAS_HIX_UNITDEVICE_ENTRY_DATA	data,
			  struct sockaddr_lpx				*host
			  )
{
	NDAS_HIX_DISCOVER_REQUEST	request;
	CFDataRef					cfdRequest = NULL;
		
	// Build Request.
	pBuildNHIXHeader(
					 &request.Header,
					 pHostGuid,
					 0,
					 NHIX_TYPE_DISCOVER,
					 sizeof(NDAS_HIX_SURRENDER_ACCESS_REQUEST)
					 );
	
	request.Data.EntryCount = 1;
	
	memcpy(&request.Data.Entry[0], data, sizeof(NDAS_HIX_UNITDEVICE_ENTRY_DATA));

	cfdRequest = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (UInt8 *) &request, sizeof(NDAS_HIX_SURRENDER_ACCESS_REQUEST), kCFAllocatorNull);

	// Send Request.
	// Per Interface.
	
	CFSocketRef				sockets[4];
	int						numInterfaces = 0;
	
	for(int i = 0; i < numberOfNics; i++) {
	
		CFDataRef	address = 0;
		struct sockaddr_lpx	addr = { 0 };
				
		// Build Socket.
		sockets[numInterfaces] = CFSocketCreate (
												 kCFAllocatorDefault,
												 PF_LPX,
												 SOCK_DGRAM,
												 0,
												 0,
												 0,
												 NULL
												 );
		if(sockets[numInterfaces] == NULL) {
			syslog(LOG_ERR, "pSendSurrenderAccess: Can't Create socket for surrender Access request.");
			
			return -1;
		}
		
		// Bind Interface Address.
		addr.slpx_family = AF_LPX;
		addr.slpx_len = sizeof(struct sockaddr_lpx);
		addr.slpx_port = 0;
		memcpy(addr.slpx_node, ethernetData[i].macAddress, 6);
		
		address = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, 
											  (UInt8 *) &addr, 
											  sizeof(struct sockaddr_lpx), 
											  kCFAllocatorNull);
		
		CFSocketError socketError = CFSocketSetAddress (
														sockets[numInterfaces],
														address
														);
		if(socketError != kCFSocketSuccess) {
			syslog(LOG_ERR, "pSendSurrenderAccess: Can't Bind.");
			continue;
		}
		
		if(address)		CFRelease(address);		address= NULL;
		
		// Create Broadcast address.
		addr.slpx_family = AF_LPX;
		addr.slpx_len = sizeof(struct sockaddr_lpx);
		memset(addr.slpx_node, 0xff, 6);
		addr.slpx_port = htons(NDAS_HIX_LISTEN_PORT);
		
		address = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, 
											  (UInt8 *) &addr, 
											  sizeof(struct sockaddr_lpx), 
											  kCFAllocatorNull);
		
		// Set Broadcast Flag.
		int on = 1;
		if(setsockopt(CFSocketGetNative(sockets[numInterfaces]), SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) != 0) {
			syslog(LOG_ERR, "pSendSurrenderAccess: Error when set option.");
			return false;
		}
		
		// Send Request.
		socketError = CFSocketSendData (
										sockets[numInterfaces],
										address,
										cfdRequest,
										0
										);
		
		if(socketError != kCFSocketSuccess) {
			syslog(LOG_ERR, "pSendSurrenderAccess: Error when send reply.");
			return false;
		}
		
		numInterfaces++;
		
		if(address)		CFRelease(address);
		
	}
		
	if(cfdRequest)	CFRelease(cfdRequest);
	
	// Receive Reply.
	int			maxfdp1;
	socklen_t			fromlen;
	fd_set	rset;
	struct timeval timeout;
	int		bResult;
	struct sockaddr_lpx	addr = { 0 };
	int count;

	int numberOfHosts = 0;

	// HostID Dictionary.
	CFMutableDictionaryRef	HostIDs = CFDictionaryCreateMutable (
																 kCFAllocatorDefault,
																 0,
																 &kCFTypeDictionaryKeyCallBacks,
																 &kCFTypeDictionaryValueCallBacks
																 );
	if (NULL == HostIDs) {
		return -1;
	}
	
retry:

	FD_ZERO(&rset);
	
	maxfdp1 = 0;
	for(count = 0; count < numInterfaces; count++) {
		FD_SET( CFSocketGetNative(sockets[count]), &rset);
		maxfdp1 = (maxfdp1 > CFSocketGetNative(sockets[count])) ? maxfdp1 : CFSocketGetNative(sockets[count]);	
	}
	maxfdp1++;
	
	timeout.tv_sec = 2;	// 2 sec.
	timeout.tv_usec = 0;
			
	int result = select(maxfdp1, &rset, NULL, NULL, &timeout);
	if(result > 0) {
		NDAS_HIX_DISCOVER_REPLY	reply;
		int len;
		
		fromlen = sizeof(struct sockaddr_lpx);
		
		// Find socket.
		for(count = 0; count < numInterfaces; count++) {
			if (FD_ISSET( CFSocketGetNative(sockets[count]), &rset)) {
				
				len = recvfrom(CFSocketGetNative(sockets[count]), &reply, sizeof(NDAS_HIX_DISCOVER_REPLY), 0, (sockaddr *)&addr, &fromlen);
				
				if ( len < sizeof(NDAS_HIX_DISCOVER_REPLY) ) {
					syslog(LOG_WARNING, "pSendDiscover: Too short HIX Discover reply len : %d\n", len);
				
					continue;
				}
					
//				syslog(LOG_ERR, "pSendDiscover: Host %2x:%2x:%2x:%2x:%2x:%2x %d\n",
//					   addr.slpx_node[0], addr.slpx_node[1], addr.slpx_node[2], 
//					   addr.slpx_node[3], addr.slpx_node[4], addr.slpx_node[5], fromlen);
				
				//				syslog(LOG_ERR, "pSendDiscover: Access : %x", reply.Data.Entry[0].AccessType);
				
				if ( len >= sizeof(NDAS_HIX_DISCOVER_REPLY) ) {
					
					if (reply.Data.EntryCount == 1
						&& memcmp(data->DeviceId, reply.Data.Entry[0].DeviceId, 6) == 0
						&& data->UnitNo == reply.Data.Entry[0].UnitNo) {
						
						// Check Duplecation.
						CFDataRef hostID = CFDataCreate(
														kCFAllocatorDefault,
														reply.Header.HostId,
														16
														);
						if (NULL == hostID) {
							goto Out;
						}
						
						if (0 == CFDictionaryGetCountOfKey(HostIDs, hostID)) {
							
							// New Host.
							CFDictionarySetValue(
												 HostIDs,
												 hostID,
												 hostID);
														
							
							syslog(LOG_DEBUG, "[%s] HIX Replay Type : %d\n", __FUNCTION__, reply.Data.Entry[0].AccessType);
							
							switch (reply.Data.Entry[0].AccessType) {
								case NHIX_UDA_WRITE_ACCESS:
								case NHIX_UDA_READ_WRITE_ACCESS:
								case NHIX_UDA_SHARED_READ_WRITE_SECONDARY_ACCESS:
								case NHIX_UDA_SHARED_READ_WRITE_PRIMARY_ACCESS:
								{
									numberOfHosts++;
									
									// Copy Address.
									if (host) {
										memcpy(host, &addr, sizeof(struct sockaddr_lpx));
									}
								}
									break;
								default:
									break;
							}	
						} else {
							syslog(LOG_INFO, "pSendDiscover: Duplicated replay.");
						}
						
						CFRelease(hostID);
					}	
				}
			}
		}
		
		goto  retry;

	} else {
		// Error or timeout.
//		syslog(LOG_ERR, "pSendDiscover: select error or timeout %d Hosts %d\n", result, numberOfHosts);
		
		bResult =  numberOfHosts;
	}
	
	//if(socketSurrender) CFRelease(socketSurrender);     

Out:
		
	if (HostIDs) {
		CFDictionaryRemoveAllValues(HostIDs);
		CFRelease(HostIDs);
	}
	
	for(count = 0; count < numInterfaces; count++) {
		if(sockets[count]) CFRelease(sockets[count]);	
	}
		
	return bResult;
}