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); });
int main(int argc, char *argv[]) { xpc_connection_t conn; if (argc < 2) { fprintf(stderr, "Usage: %s <mach service name>\n", argv[0]); return (1); } conn = xpc_connection_create_mach_service(argv[1], NULL, XPC_CONNECTION_MACH_SERVICE_LISTENER); xpc_connection_set_event_handler(conn, ^(xpc_object_t peer) { printf("New connection, peer=%p\n", peer); xpc_connection_set_event_handler(peer, ^(xpc_object_t event) { if (event == XPC_ERROR_CONNECTION_INVALID) { printf("Connection closed by remote end\n"); return; } if (xpc_get_type(event) != XPC_TYPE_DICTIONARY) { printf("Received something else than a dictionary!\n"); return; } printf("Message received: %p\n", event); printf("%s\n", xpc_copy_description(event)); xpc_object_t resp = xpc_dictionary_create(NULL, NULL, 0); xpc_dictionary_set_string(resp, "foo", "bar"); xpc_connection_send_message(peer, resp); });
static xpc_object_t auth_item_copy_auth_item_xpc(auth_item_t item) { xpc_object_t xpc_data = xpc_dictionary_create(NULL, NULL, 0); xpc_dictionary_set_string(xpc_data, AUTH_XPC_ITEM_NAME, item->data.name); if (item->data.value) { xpc_dictionary_set_data(xpc_data, AUTH_XPC_ITEM_VALUE, item->data.value, item->data.valueLength); } xpc_dictionary_set_uint64(xpc_data, AUTH_XPC_ITEM_FLAGS, item->data.flags); xpc_dictionary_set_uint64(xpc_data, AUTH_XPC_ITEM_TYPE, item->type); return xpc_data; }
static int vmnet_get_mac_address_from_uuid(char *guest_uuid_str) { /* * from vmn_create() in https://github.com/mist64/xhyve/blob/master/src/pci_virtio_vmnet.c */ 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; 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); uuid_from_string(guest_uuid_str, &uuid, &uuid_status); if (uuid_status != uuid_s_ok) { fprintf(stderr, "Invalid UUID\n"); return -1; } xpc_dictionary_set_uuid(interface_desc, vmnet_interface_id_key, uuid); iface = NULL; iface_status = 0; 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; } printf("%s\n", xpc_dictionary_get_string(interface_param, vmnet_mac_address_key)); dispatch_semaphore_signal(iface_created); });
xpc_object_t xpc_copy(xpc_object_t obj) { struct xpc_object *xo, *xotmp; const void *newdata; xo = obj; switch (xo->xo_xpc_type) { case _XPC_TYPE_BOOL: case _XPC_TYPE_INT64: case _XPC_TYPE_UINT64: case _XPC_TYPE_DATE: case _XPC_TYPE_ENDPOINT: return _xpc_prim_create(xo->xo_xpc_type, xo->xo_u, 1); case _XPC_TYPE_STRING: return xpc_string_create(strdup( xpc_string_get_string_ptr(xo))); case _XPC_TYPE_DATA: newdata = xpc_data_get_bytes_ptr(obj); return (xpc_data_create(newdata, xpc_data_get_length(obj))); case _XPC_TYPE_DICTIONARY: xotmp = xpc_dictionary_create(NULL, NULL, 0); xpc_dictionary_apply(obj, ^(const char *k, xpc_object_t v) { xpc_dictionary_set_value(xotmp, k, xpc_copy(v)); return (bool)true; }); return (xotmp); case _XPC_TYPE_ARRAY: xotmp = xpc_array_create(NULL, 0); xpc_array_apply(obj, ^(size_t idx, xpc_object_t v) { xpc_array_set_value(xotmp, idx, xpc_copy(v)); return ((bool)true); });
Message(const char *function) { init(); obj = xpc_dictionary_create(NULL, NULL, 0); xpc_dictionary_set_string(obj, "function", function); }
/* * 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); });