diff --git a/network.go b/network.go index 385b2f4..0250e6c 100644 --- a/network.go +++ b/network.go @@ -23,7 +23,6 @@ import ( // virtual machine send and receive packets on the same physical interface but have distinct network layers. // // The BridgedNetwork can be used with a BridgedNetworkDeviceAttachment to set up a network device NetworkDeviceConfiguration. -// TODO(codehex): implement... // see: https://developer.apple.com/documentation/virtualization/vzbridgednetworkinterface?language=objc type BridgedNetwork interface { objc.NSObject @@ -39,6 +38,48 @@ type BridgedNetwork interface { LocalizedDisplayName() string } +// NewBridgedNetwork creates a new BridgedNetwork with identifier. +// +// This is only supported on macOS 11 and newer, error will +// be returned on older versions. +func NetworkInterfaces() []BridgedNetwork { + nsArray := objc.NewNSArray( + C.VZBridgedNetworkInterface_networkInterfaces(), + ) + ptrs := nsArray.ToPointerSlice() + networkInterfaces := make([]BridgedNetwork, len(ptrs)) + for i, ptr := range ptrs { + networkInterfaces[i] = &baseBridgedNetwork{ + pointer: objc.NewPointer(ptr), + } + } + return networkInterfaces +} + +type baseBridgedNetwork struct { + *pointer +} + +func (*baseBridgedNetwork) NetworkInterfaces() []BridgedNetwork { + return NetworkInterfaces() +} + +// Identifier returns the unique identifier for this interface. +// +// The identifier is the BSD name associated with the interface (e.g. "en0"). +func (b *baseBridgedNetwork) Identifier() string { + cstring := (*char)(C.VZBridgedNetworkInterface_identifier(objc.Ptr(b))) + return cstring.String() +} + +// LocalizedDisplayName returns a display name if available (e.g. "Ethernet"). +// +// If no display name is available, the identifier is returned. +func (b *baseBridgedNetwork) LocalizedDisplayName() string { + cstring := (*char)(C.VZBridgedNetworkInterface_localizedDisplayName(objc.Ptr(b))) + return cstring.String() +} + // Network device attachment using network address translation (NAT) with outside networks. // // Using the NAT attachment type, the host serves as router and performs network address translation diff --git a/virtualization_11.h b/virtualization_11.h index 61b5d79..f5b6aab 100644 --- a/virtualization_11.h +++ b/virtualization_11.h @@ -64,6 +64,9 @@ void setStorageDevicesVZVirtualMachineConfiguration(void *config, void *newVZFileHandleSerialPortAttachment(int readFileDescriptor, int writeFileDescriptor); void *newVZFileSerialPortAttachment(const char *filePath, bool shouldAppend, void **error); void *newVZVirtioConsoleDeviceSerialPortConfiguration(void *attachment); +void *VZBridgedNetworkInterface_networkInterfaces(void); +const char *VZBridgedNetworkInterface_identifier(void *networkInterface); +const char *VZBridgedNetworkInterface_localizedDisplayName(void *networkInterface); void *newVZBridgedNetworkDeviceAttachment(void *networkInterface); void *newVZNATNetworkDeviceAttachment(void); void *newVZFileHandleNetworkDeviceAttachment(int fileDescriptor); diff --git a/virtualization_11.m b/virtualization_11.m index 518367d..700b303 100644 --- a/virtualization_11.m +++ b/virtualization_11.m @@ -392,6 +392,50 @@ void setStorageDevicesVZVirtualMachineConfiguration(void *config, RAISE_UNSUPPORTED_MACOS_EXCEPTION(); } +/*! + @abstract Return the list of network interfaces available for bridging. + @discussion + A bridged interface is shared between the virtual machine and the host system. Both host and virtual machine send and receive packets on the same physical interface but have distinct network layers. + + VZBridgedNetworkInterface cannot be instantiated directly. It can be used with a VZBridgedNetworkDeviceAttachment to set up a network device VZNetworkDeviceConfiguration. + + @seealso VZBridgedNetworkDeviceAttachment + @seealso VZNATNetworkDeviceAttachment + @seealso VZNetworkDeviceConfiguration + */ +void *VZBridgedNetworkInterface_networkInterfaces() +{ + if (@available(macOS 11, *)) { + return [VZBridgedNetworkInterface networkInterfaces]; // NSArray + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Return the unique identifier for this interface. The identifier is the BSD name associated with the interface (e.g. "en0"). + */ +const char *VZBridgedNetworkInterface_identifier(void *networkInterface) +{ + if (@available(macOS 11, *)) { + return [[(VZBridgedNetworkInterface *)networkInterface identifier] UTF8String]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Return a display name if available (e.g. "Ethernet"). + */ +const char *VZBridgedNetworkInterface_localizedDisplayName(void *networkInterface) +{ + if (@available(macOS 11, *)) { + return [[(VZBridgedNetworkInterface *)networkInterface localizedDisplayName] UTF8String]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + /*! @abstract Create a new Network device attachment bridging a host physical interface with a virtual network device. @param networkInterface a network interface that bridges a physical interface.