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 */ Boolean _CFServerStart(_CFServerRef server, CFStringRef name, CFStringRef type, UInt32 port) { Server* s = (Server*)server; CFDataRef address = NULL; do { unsigned i; CFRunLoopRef rl = CFRunLoopGetCurrent(); CFAllocatorRef alloc = CFGetAllocator(server); struct sockaddr_in addr4; struct sockaddr_in6 addr6; // Make sure the port is valid (0 - 65535). if ((port & 0xFFFF0000U) != 0) break; // NULL means to use the machine name. if (name == NULL) name = _kCFServerEmptyString; for (i = 0; i < (sizeof(s->_sockets) / sizeof(s->_sockets[0])); i++) { // Create the run loop source for putting on the run loop. CFRunLoopSourceRef src = CFSocketCreateRunLoopSource(alloc, s->_sockets[i], 0); if (src == NULL) break; // Add the run loop source to the current run loop and default mode. CFRunLoopAddSource(rl, src, kCFRunLoopCommonModes); CFRelease(src); } memset(&addr4, 0, sizeof(addr4)); // Put the local port and address into the native address. #if !defined(__WIN32__) addr4.sin_len = sizeof(addr4); #endif addr4.sin_family = AF_INET; addr4.sin_port = htons((UInt16)port); addr4.sin_addr.s_addr = htonl(INADDR_ANY); // Wrap the native address structure for CFSocketCreate. address = CFDataCreateWithBytesNoCopy(alloc, (const UInt8*)&addr4, sizeof(addr4), kCFAllocatorNull); // If it failed to create the address data, bail. if (address == NULL) break; // Set the local binding which causes the socket to start listening. if (CFSocketSetAddress(s->_sockets[0], address) != kCFSocketSuccess) break; CFRelease(address); address = CFSocketCopyAddress(s->_sockets[0]); memcpy(&addr4, CFDataGetBytePtr(address), CFDataGetLength(address)); port = ntohs(addr4.sin_port); CFRelease(address); memset(&addr6, 0, sizeof(addr6)); // Put the local port and address into the native address. addr6.sin6_family = AF_INET6; #ifndef __WIN32__ addr6.sin6_port = htons((UInt16)port); addr6.sin6_len = sizeof(addr6); memcpy(&(addr6.sin6_addr), &in6addr_any, sizeof(addr6.sin6_addr)); #else #ifndef __MINGW32__ // real MS headers have this IN6ADDR_SETANY(addr6); addr6.sin6_port = htons((UInt16)port); #else addr6.sin6_port = htons((UInt16)port); // mingw's w32 headers have this INIT macro instead, for some odd reason struct sockaddr_in6 in6addr_any = IN6ADDR_ANY_INIT; memcpy(&(addr6.sin6_addr), &in6addr_any, sizeof(addr6.sin6_addr)); #endif #endif // Wrap the native address structure for CFSocketCreate. address = CFDataCreateWithBytesNoCopy(alloc, (const UInt8*)&addr6, sizeof(addr6), kCFAllocatorNull); // Set the local binding which causes the socket to start listening. if (CFSocketSetAddress(s->_sockets[1], address) != kCFSocketSuccess) break; // Save the name, service type and port. s->_name = CFRetain(name); s->_type = type ? CFRetain(type) : NULL; s->_port = port; #if defined(__MACH__) // Attempt to register the service on the network. if (type && !_ServerCreateAndRegisterNetService(s)) break; #endif // Release this since it's not needed any longer. CFRelease(address); return TRUE; } while (0); // Handle the error cleanup. // Release the address data if it was created. if (address) CFRelease(address); // Kill the socket if it was created. _ServerReleaseSocket(s); return FALSE; }
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; }