106 lines
3.1 KiB
Objective-C
106 lines
3.1 KiB
Objective-C
#import "vmnet.h"
|
|
|
|
void _vmnet_start(interface_ref *interface, char *host_interface, uint64_t *max_packet_size) {
|
|
xpc_object_t interface_desc = xpc_dictionary_create(NULL, NULL, 0);
|
|
xpc_dictionary_set_uint64(interface_desc, vmnet_operation_mode_key,
|
|
VMNET_BRIDGED_MODE);
|
|
|
|
xpc_dictionary_set_string(interface_desc, vmnet_shared_interface_name_key, host_interface);
|
|
|
|
dispatch_queue_t interface_start_queue =
|
|
dispatch_queue_create("vmnet-start", DISPATCH_QUEUE_SERIAL);
|
|
dispatch_semaphore_t interface_start_semaphore = dispatch_semaphore_create(0);
|
|
|
|
__block interface_ref _interface;
|
|
__block vmnet_return_t interface_status;
|
|
__block uint64_t _max_packet_size = 0;
|
|
|
|
_interface = vmnet_start_interface(
|
|
interface_desc, interface_start_queue,
|
|
^(vmnet_return_t status, xpc_object_t interface_param) {
|
|
interface_status = status;
|
|
|
|
if (status == VMNET_SUCCESS) {
|
|
_max_packet_size = xpc_dictionary_get_uint64(
|
|
interface_param, vmnet_max_packet_size_key);
|
|
}
|
|
|
|
dispatch_semaphore_signal(interface_start_semaphore);
|
|
});
|
|
|
|
dispatch_semaphore_wait(interface_start_semaphore, DISPATCH_TIME_FOREVER);
|
|
|
|
dispatch_release(interface_start_queue);
|
|
xpc_release(interface_desc);
|
|
|
|
if (interface_status != VMNET_SUCCESS) {
|
|
return;
|
|
}
|
|
|
|
*interface = _interface;
|
|
*max_packet_size = _max_packet_size;
|
|
}
|
|
|
|
void _vmnet_stop(interface_ref interface) {
|
|
if (interface == NULL) {
|
|
return;
|
|
}
|
|
|
|
dispatch_queue_t interface_stop_queue =
|
|
dispatch_queue_create("vmnet-stop", DISPATCH_QUEUE_SERIAL);
|
|
dispatch_semaphore_t interface_stop_semaphore = dispatch_semaphore_create(0);
|
|
|
|
vmnet_stop_interface(interface, interface_stop_queue,
|
|
^(vmnet_return_t status) {
|
|
dispatch_semaphore_signal(interface_stop_semaphore);
|
|
});
|
|
|
|
dispatch_semaphore_wait(interface_stop_semaphore, DISPATCH_TIME_FOREVER);
|
|
dispatch_release(interface_stop_queue);
|
|
}
|
|
|
|
void _vmnet_write(interface_ref interface, void *bytes, size_t bytes_size) {
|
|
if (interface == NULL) {
|
|
return;
|
|
}
|
|
|
|
struct iovec packets_iovec = {
|
|
.iov_base = bytes,
|
|
.iov_len = bytes_size,
|
|
};
|
|
|
|
struct vmpktdesc packets = {
|
|
.vm_pkt_size = bytes_size,
|
|
.vm_pkt_iov = &packets_iovec,
|
|
.vm_pkt_iovcnt = 1,
|
|
.vm_flags = 0,
|
|
};
|
|
|
|
int packets_count = packets.vm_pkt_iovcnt;
|
|
vmnet_write(interface, &packets, &packets_count);
|
|
}
|
|
|
|
void _vmnet_read(interface_ref interface, uint64_t max_packet_size,
|
|
void **bytes, size_t *bytes_size) {
|
|
struct iovec packets_iovec = {
|
|
.iov_base = malloc(max_packet_size),
|
|
.iov_len = max_packet_size,
|
|
};
|
|
|
|
struct vmpktdesc packets = {
|
|
.vm_pkt_size = max_packet_size,
|
|
.vm_pkt_iov = &packets_iovec,
|
|
.vm_pkt_iovcnt = 1,
|
|
.vm_flags = 0,
|
|
};
|
|
|
|
int packets_count = 1;
|
|
vmnet_return_t status = vmnet_read(interface, &packets, &packets_count);
|
|
|
|
if (status != VMNET_SUCCESS || packets_count == 0) {
|
|
return;
|
|
}
|
|
|
|
*bytes = packets.vm_pkt_iov->iov_base;
|
|
*bytes_size = packets.vm_pkt_size;
|
|
}
|