CAMLprim value caml_init_vmnet(value v_mode) { CAMLparam1(v_mode); CAMLlocal3(v_iface_ref,v_res,v_mac); xpc_object_t interface_desc = xpc_dictionary_create(NULL, NULL, 0); xpc_dictionary_set_uint64(interface_desc, vmnet_operation_mode_key, Int_val(v_mode)); uuid_t uuid; uuid_generate_random(uuid); xpc_dictionary_set_uuid(interface_desc, vmnet_interface_id_key, uuid); __block interface_ref iface = NULL; __block vmnet_return_t iface_status = 0; __block unsigned char *mac = malloc(6); if (!mac) caml_raise_out_of_memory (); __block unsigned int mtu = 0; __block unsigned int max_packet_size = 0; dispatch_queue_t if_create_q = dispatch_queue_create("org.openmirage.vmnet.create", DISPATCH_QUEUE_SERIAL); dispatch_semaphore_t iface_created = dispatch_semaphore_create(0); iface = vmnet_start_interface(interface_desc, if_create_q, ^(vmnet_return_t status, xpc_object_t interface_param) { iface_status = status; if (status != VMNET_SUCCESS || !interface_param) { dispatch_semaphore_signal(iface_created); return; } //printf("mac desc: %s\n", xpc_copy_description(xpc_dictionary_get_value(interface_param, vmnet_mac_address_key))); const char *macStr = xpc_dictionary_get_string(interface_param, vmnet_mac_address_key); unsigned char lmac[6]; if (sscanf(macStr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &lmac[0], &lmac[1], &lmac[2], &lmac[3], &lmac[4], &lmac[5]) != 6) errx(1, "Unexpected MAC address received from vmnet"); memcpy(mac, lmac, 6); mtu = xpc_dictionary_get_uint64(interface_param, vmnet_mtu_key); max_packet_size = xpc_dictionary_get_uint64(interface_param, vmnet_max_packet_size_key); dispatch_semaphore_signal(iface_created); });
/* * Create an interface for the guest using Apple's vmnet framework. * * The interface works in VMNET_SHARED_MODE which allows for packets * of the guest to reach other guests and the Internet. * * See also: https://developer.apple.com/library/mac/documentation/vmnet/Reference/vmnet_Reference/index.html */ static int vmn_create(struct pci_vtnet_softc *sc) { xpc_object_t interface_desc; uuid_t uuid; __block interface_ref iface; __block vmnet_return_t iface_status; dispatch_semaphore_t iface_created; dispatch_queue_t if_create_q; dispatch_queue_t if_q; struct vmnet_state *vms; uint32_t uuid_status; interface_desc = xpc_dictionary_create(NULL, NULL, 0); xpc_dictionary_set_uint64(interface_desc, vmnet_operation_mode_key, VMNET_SHARED_MODE); if (guest_uuid_str != NULL) { uuid_from_string(guest_uuid_str, &uuid, &uuid_status); if (uuid_status != uuid_s_ok) { return (-1); } } else { uuid_generate_random(uuid); } xpc_dictionary_set_uuid(interface_desc, vmnet_interface_id_key, uuid); iface = NULL; iface_status = 0; vms = malloc(sizeof(struct vmnet_state)); if (!vms) { return (-1); } if_create_q = dispatch_queue_create("org.xhyve.vmnet.create", DISPATCH_QUEUE_SERIAL); iface_created = dispatch_semaphore_create(0); iface = vmnet_start_interface(interface_desc, if_create_q, ^(vmnet_return_t status, xpc_object_t interface_param) { iface_status = status; if (status != VMNET_SUCCESS || !interface_param) { dispatch_semaphore_signal(iface_created); return; } if (sscanf(xpc_dictionary_get_string(interface_param, vmnet_mac_address_key), "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &vms->mac[0], &vms->mac[1], &vms->mac[2], &vms->mac[3], &vms->mac[4], &vms->mac[5]) != 6) { assert(0); } vms->mtu = (unsigned) xpc_dictionary_get_uint64(interface_param, vmnet_mtu_key); vms->max_packet_size = (unsigned) xpc_dictionary_get_uint64(interface_param, vmnet_max_packet_size_key); dispatch_semaphore_signal(iface_created); });
static void security_auth_peer_event_handler(xpc_connection_t connection, xpc_object_t event) { __block OSStatus status = errAuthorizationDenied; connection_t conn = (connection_t)xpc_connection_get_context(connection); require_action(conn != NULL, done, LOGE("xpc[%i]: process context not found", xpc_connection_get_pid(connection))); CFRetainSafe(conn); xpc_type_t type = xpc_get_type(event); if (type == XPC_TYPE_ERROR) { if (event == XPC_ERROR_CONNECTION_INVALID) { // The client process on the other end of the connection has either // crashed or cancelled the connection. After receiving this error, // the connection is in an invalid state, and you do not need to // call xpc_connection_cancel(). Just tear down any associated state // here. LOGV("xpc[%i]: client disconnected", xpc_connection_get_pid(connection)); connection_destory_agents(conn); } else if (event == XPC_ERROR_TERMINATION_IMMINENT) { // Handle per-connection termination cleanup. LOGD("xpc[%i]: per-connection termination", xpc_connection_get_pid(connection)); } } else { assert(type == XPC_TYPE_DICTIONARY); xpc_object_t reply = xpc_dictionary_create_reply(event); require(reply != NULL, done); uint64_t auth_type = xpc_dictionary_get_uint64(event, AUTH_XPC_TYPE); LOGV("xpc[%i]: received message type=%llu", connection_get_pid(conn), auth_type); switch (auth_type) { case AUTHORIZATION_CREATE: status = authorization_create(conn,event,reply); break; case AUTHORIZATION_CREATE_WITH_AUDIT_TOKEN: status = authorization_create_with_audit_token(conn,event,reply); break; case AUTHORIZATION_FREE: status = authorization_free(conn,event,reply); break; case AUTHORIZATION_COPY_RIGHTS: status = authorization_copy_rights(conn,event,reply); break; case AUTHORIZATION_COPY_INFO: status = authorization_copy_info(conn,event,reply); break; case AUTHORIZATION_MAKE_EXTERNAL_FORM: status = authorization_make_external_form(conn,event,reply); break; case AUTHORIZATION_CREATE_FROM_EXTERNAL_FORM: status = authorization_create_from_external_form(conn,event,reply); break; case AUTHORIZATION_RIGHT_GET: status = authorization_right_get(conn,event,reply); break; case AUTHORIZATION_RIGHT_SET: status = authorization_right_set(conn,event,reply); break; case AUTHORIZATION_RIGHT_REMOVE: status = authorization_right_remove(conn,event,reply); break; case SESSION_SET_USER_PREFERENCES: status = session_set_user_preferences(conn,event,reply); break; case AUTHORIZATION_DISMISS: connection_destory_agents(conn); status = errAuthorizationSuccess; break; case AUTHORIZATION_ENABLE_SMARTCARD: status = authorization_enable_smartcard(conn,event,reply); break; case AUTHORIZATION_SETUP: { mach_port_t bootstrap = xpc_dictionary_copy_mach_send(event, AUTH_XPC_BOOTSTRAP); if (!process_set_bootstrap(connection_get_process(conn), bootstrap)) { if (bootstrap != MACH_PORT_NULL) { mach_port_deallocate(mach_task_self(), bootstrap); } } } status = errAuthorizationSuccess; break; #if DEBUG case AUTHORIZATION_DEV: server_dev(); break; #endif default: break; } xpc_dictionary_set_int64(reply, AUTH_XPC_STATUS, status); xpc_connection_send_message(connection, reply); xpc_release(reply); } done: CFReleaseSafe(conn); }