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); }
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(); } }
/* 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; }
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; } }
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; }
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; }
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; }