/**************************************************************************
    Socket Notifiers
 *************************************************************************/
void qt_mac_socket_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef,
                            const void *, void *info)
{

    QCFSocketNotifier *cfSocketNotifier = static_cast<QCFSocketNotifier *>(info);
    int nativeSocket = CFSocketGetNative(s);
    MacSocketInfo *socketInfo = cfSocketNotifier->macSockets.value(nativeSocket);
    QEvent notifierEvent(QEvent::SockAct);

    // There is a race condition that happen where we disable the notifier and
    // the kernel still has a notification to pass on. We then get this
    // notification after we've successfully disabled the CFSocket, but our Qt
    // notifier is now gone. The upshot is we have to check the notifier
    // every time.
    if (callbackType == kCFSocketReadCallBack) {
        if (socketInfo->readNotifier)
            QGuiApplication::sendEvent(socketInfo->readNotifier, &notifierEvent);
    } else if (callbackType == kCFSocketWriteCallBack) {
        if (socketInfo->writeNotifier)
            QGuiApplication::sendEvent(socketInfo->writeNotifier, &notifierEvent);
    }

    if (cfSocketNotifier->maybeCancelWaitForMoreEvents)
        cfSocketNotifier->maybeCancelWaitForMoreEvents(cfSocketNotifier->eventDispatcher);
}
static void
eventCallback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
{
	int			so		= CFSocketGetNative(s);
	int			status;
	char			buf[1024];
	struct kern_event_msg	*ev_msg		= (struct kern_event_msg *)&buf[0];
	int			offset		= 0;

	status = recv(so, &buf, sizeof(buf), 0);
	if (status == -1) {
		SCLog(TRUE, LOG_ERR, CFSTR("recv() failed: %s"), strerror(errno));
		goto error;
	}

	cache_open();

	while (offset < status) {
		if ((offset + ev_msg->total_size) > status) {
			SCLog(TRUE, LOG_NOTICE, CFSTR("missed SYSPROTO_EVENT event, buffer not big enough"));
			break;
		}

		switch (ev_msg->vendor_code) {
			case KEV_VENDOR_APPLE :
				switch (ev_msg->kev_class) {
					case KEV_NETWORK_CLASS :
						processEvent_Apple_Network(ev_msg);
						break;
					case KEV_IOKIT_CLASS :
						processEvent_Apple_IOKit(ev_msg);
						break;
					default :
						/* unrecognized (Apple) event class */
						logEvent(CFSTR("New (Apple) class"), ev_msg);
						break;
				}
				break;
			default :
				/* unrecognized vendor code */
				logEvent(CFSTR("New vendor"), ev_msg);
				break;
		}
		offset += ev_msg->total_size;
		ev_msg = (struct kern_event_msg *)&buf[offset];
	}

	cache_write(store);
	cache_close();

	return;

    error :

	SCLog(TRUE, LOG_ERR, CFSTR("kernel event monitor disabled."));
	CFSocketInvalidate(s);
	return;

}
Example #3
0
static void _cf_socket_callback( CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info ) {
  struct MIDIRunloopSource * source = info;
  int i = CFSocketGetNative( s );
  fd_set fds;
  FD_ZERO(&fds);
  FD_SET(i, &fds);
  switch( callbackType ) {
    case kCFSocketReadCallBack:
      if( FD_ISSET(i, &(source->readfds)) && source->read != NULL ) {
        (*source->read)( source->info, source->nfds, &(fds) );
      }
      break;
    case kCFSocketWriteCallBack:
      if( FD_ISSET(i, &(source->writefds)) && source->write != NULL ) {
        (*source->write)( source->info, source->nfds, &(fds) );
      }
      break;
  }
}
Example #4
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);
}
Example #5
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();
	}
}
void __CFSocketCallBack(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info) {
    // Extract the context
    tnet_transport_t *transport = (tnet_transport_t *) info;
	transport_context_t *context = transport->context;
    
    // Extract the native socket
    int fd = CFSocketGetNative(s);
    transport_socket_t *sock = (transport_socket_t *) getSocket(context, fd);

    /* lock context */
    tsk_safeobj_lock(context);
    
    switch (callbackType) {
        case kCFSocketReadCallBack:
        {
            int ret;
            tsk_size_t len = 0;
            void* buffer = 0;
            tnet_transport_event_t* e;
            
            if (tnet_ioctlt(sock->fd, FIONREAD, &len) < 0) {
                TNET_PRINT_LAST_ERROR("IOCTLT FAILED.");
                break;
            }
            
            if (!len) {
                TSK_DEBUG_WARN("IOCTLT returned zero.");
                TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, sock->fd);
                removeSocket(sock, context);
                break;
            }
            
            if (!(buffer = tsk_calloc(len, sizeof(uint8_t)))) {
                TSK_DEBUG_ERROR("TSK_CALLOC FAILED.");
                break;
            }
            
            if ((ret = tnet_sockfd_recv(sock->fd, buffer, len, 0)) < 0) {
                TSK_FREE(buffer);
                removeSocket(sock, context);
                TNET_PRINT_LAST_ERROR("recv have failed.");
                break;
            }
            else if ((len != (tsk_size_t)ret) && len) { // useless test ?
                len = (tsk_size_t)ret;
                // buffer = tsk_realloc(buffer, len);
            }
            
            TSK_DEBUG_INFO("__CFSocketCallBack -> %u bytes read", len);
            
            e = tnet_transport_event_create(event_data, transport->callback_data, sock->fd);
            e->data = buffer;
            e->size = len;
            
            TSK_RUNNABLE_ENQUEUE_OBJECT(TSK_RUNNABLE(transport), e);
            
            break;
        }
        case kCFSocketAcceptCallBack:
        case kCFSocketConnectCallBack:
        case kCFSocketDataCallBack:
        case kCFSocketWriteCallBack:
        default:
        {
            // Not Implemented
            assert(42 == 0);
            break;
        }
    }
    
    /* unlock context */
    tsk_safeobj_unlock(context);
}
Example #7
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;
}
Example #8
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;
    }
}
Example #9
0
void iSCSIDProcessIncomingRequest(CFSocketRef socket,
                                  CFSocketCallBackType callbackType,
                                  CFDataRef address,
                                  const void * data,
                                  void * info)
{
    // File descriptor associated with the socket we're using
    static int fd = 0;

    // If this is the first connection, initialize the user client for the
    // iSCSI initiator kernel extension
    if(fd == 0) {
        iSCSIInitialize(CFRunLoopGetCurrent());

        // Wait for an incoming connection; upon timeout quit
        struct sockaddr_storage peerAddress;
        socklen_t length = sizeof(peerAddress);

        // Get file descriptor associated with the connection
        fd = accept(CFSocketGetNative(socket),(struct sockaddr *)&peerAddress,&length);
    }

    struct iSCSIDCmd cmd;

    while(recv(fd,&cmd,sizeof(cmd),MSG_PEEK) == sizeof(cmd)) {

        recv(fd,&cmd,sizeof(cmd),MSG_WAITALL);

        errno_t error = 0;
        switch(cmd.funcCode)
        {
        case kiSCSIDLogin:
            error = iSCSIDLogin(fd,(iSCSIDCmdLogin*)&cmd);
            break;
        case kiSCSIDLogout:
            error = iSCSIDLogout(fd,(iSCSIDCmdLogout*)&cmd);
            break;
        case kiSCSIDCreateArrayOfActiveTargets:
            error = iSCSIDCreateArrayOfActiveTargets(fd,(iSCSIDCmdCreateArrayOfActiveTargets*)&cmd);
            break;
        case kiSCSIDCreateArrayOfActivePortalsForTarget:
            error = iSCSIDCreateArrayofActivePortalsForTarget(fd,(iSCSIDCmdCreateArrayOfActivePortalsForTarget*)&cmd);
            break;
        case kiSCSIDIsTargetActive:
            error = iSCSIDIsTargetActive(fd,(iSCSIDCmdIsTargetActive*)&cmd);
            break;
        case kiSCSIDIsPortalActive:
            error = iSCSIDIsPortalActive(fd,(iSCSIDCmdIsPortalActive*)&cmd);
            break;
        case kiSCSIDQueryPortalForTargets:
            error = iSCSIDQueryPortalForTargets(fd,(iSCSIDCmdQueryPortalForTargets*)&cmd);
            break;
        case kiSCSIDQueryTargetForAuthMethod:
            error = iSCSIDQueryTargetForAuthMethod(fd,(iSCSIDCmdQueryTargetForAuthMethod*)&cmd);
            break;
        case kiSCSIDCreateCFPropertiesForSession:
            error = iSCSIDCreateCFPropertiesForSession(fd,(iSCSIDCmdCreateCFPropertiesForSession*)&cmd);
            break;
        case kiSCSIDCreateCFPropertiesForConnection:
            error = iSCSIDCreateCFPropertiesForConnection(fd,(iSCSIDCmdCreateCFPropertiesForConnection*)&cmd);
            break;
        default:
            // Close our connection to the iSCSI kernel extension
            iSCSICleanup();
            close(fd);
            fd = 0;
        };
    }
}
Example #10
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;
}
Example #11
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;
}
Example #12
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;
}