Programmatic IP Discovery for VZVirtualMachine in an App Store Sandbox

Hi everyone,

I am developing a macOS virtualization manager (VirtualProg) using the Virtualization.framework. The application is distributed via the Mac App Store, so it operates strictly within the App Store Sandbox.

I am looking for a reliable, programmatic way to discover the IP address assigned to a guest (both macOS and Linux).

Is there a recommended "Sandbox-safe" API or pattern within the Virtualization framework—or a lower-level networking entitlement—that allows a host application to retrieve the guest's assigned IP address?

Ideally, I am looking for a solution that does not require the user to manually install a non-sandboxed helper tool.

Thanks in advance for any insights or guidance!

Answered by DTS Engineer in 883963022

i [want] to determine ip address of guest os without any cooperation from guest.

Thanks for confirming that.

This is a fundamentally tricky problem to solve, at least in the general case. The guest chooses how it’s going to assign IP addresses to an interface, and the host has no direct control over that choice.

However, there may be an indirect way to do this:

  • Virtualization framework lets you create a network that’s backed by a vmnet network (VZVmnetNetworkDeviceAttachment).
  • vmnet framework lets your configure a network with a specific DHCP mapping (vmnet_network_configuration_add_dhcp_reservation).

There are some significant caveats:

  • The guest must default to using DHCP.
  • You can’t support bridged mode (VMNET_BRIDGED_MODE), because in bridged mode the guest isn’t talking to the vmnet DHCP server.
  • This is all new in macOS 26.

But otherwise I think it’ll work. So please try it out and let me know how you get along.

ps It’s better to reply as a reply, rather than in the comments; see Quinn’s Top Ten DevForums Tips for this and other titbits.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I want to make sure I understand your requirements here. You don’t expect to be running any helper code within the guest, right? So you want to discover the IP address (well, addresses) that the guest OS assigned to the shared interface without any cooperation from the guest?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

i [want] to determine ip address of guest os without any cooperation from guest.

Thanks for confirming that.

This is a fundamentally tricky problem to solve, at least in the general case. The guest chooses how it’s going to assign IP addresses to an interface, and the host has no direct control over that choice.

However, there may be an indirect way to do this:

  • Virtualization framework lets you create a network that’s backed by a vmnet network (VZVmnetNetworkDeviceAttachment).
  • vmnet framework lets your configure a network with a specific DHCP mapping (vmnet_network_configuration_add_dhcp_reservation).

There are some significant caveats:

  • The guest must default to using DHCP.
  • You can’t support bridged mode (VMNET_BRIDGED_MODE), because in bridged mode the guest isn’t talking to the vmnet DHCP server.
  • This is all new in macOS 26.

But otherwise I think it’ll work. So please try it out and let me know how you get along.

ps It’s better to reply as a reply, rather than in the comments; see Quinn’s Top Ten DevForums Tips for this and other titbits.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thank you for the reply. Is there any example with code on how to do this?

never mind i managed to get the sample code from apple container github repository. now i can reserve a pool of ip address and assign ip address to guest from that. thanks for the heads up. it seem to be that VZVmnetNetworkDeviceAttachment is only avaialble for mac os 26 how can accomplist this with 14 and 15. any idea?

And aslo after doing this i would like to do the port forwarding. Any idea how can i accomplish this.

my code looks likes this

import Virtualization
import vmnet
import Darwin

@available(macOS 26.0, *)
public class SharedVMNetManager {
    
    public static let shared = SharedVMNetManager()
    
    private var activeNetwork: vmnet_network_ref?
    private var activeConfig: vmnet_network_configuration_ref?
    
    // Track which MACs we have already told the kernel about
    private var registeredMacs: Set<String> = []
    private let lock = NSLock()
    
    private init() {}
    
    public func getAttachment(macAddress: String, reservedIP: String) -> VZVmnetNetworkDeviceAttachment? {
        lock.lock()
        defer { lock.unlock() }
        
        var status: vmnet_return_t = .VMNET_SUCCESS
        
        // 1. Check if we've already initialized the hardware switch
        if let config = activeConfig, let network = activeNetwork {
            // ONLY add the reservation if we haven't done it for this MAC yet
            if !registeredMacs.contains(macAddress) {
                addReservation(to: config, mac: macAddress, ip: reservedIP)
                registeredMacs.insert(macAddress)
            }
            return VZVmnetNetworkDeviceAttachment(network: network)
        }
        
        // 2. First-time initialization
        let mode: vmnet.operating_modes_t = .VMNET_SHARED_MODE
        guard let config = vmnet_network_configuration_create(mode, &status),
              status == .VMNET_SUCCESS else { return nil }
        
        // Define Subnet
        var subnet = in_addr(), mask = in_addr()
        inet_pton(AF_INET, "192.168.142.1", &subnet)
        inet_pton(AF_INET, "255.255.255.0", &mask)
        vmnet_network_configuration_set_ipv4_subnet(config, &subnet, &mask)
        
        // Define the Pool (Make sure your reserved IP is INSIDE this range)
        /*var start = in_addr(), end = in_addr()
        inet_pton(AF_INET, "192.168.142.10", &start)
        inet_pton(AF_INET, "192.168.142.50", &end)
        vmnet_network_configuration_set_ipv4_pool(config, &start, &end)*/

        // 3. Register the first MAC before the network starts
        addReservation(to: config, mac: macAddress, ip: reservedIP)
        registeredMacs.insert(macAddress)
        
        // 4. Commit and Create Network
        guard let network = vmnet_network_create(config, &status),
              status == .VMNET_SUCCESS else { return nil }
        
        self.activeConfig = config
        self.activeNetwork = network
        
        return VZVmnetNetworkDeviceAttachment(network: network)
    }
    
    private func addReservation(to config: vmnet_network_configuration_ref, mac: String, ip: String) {
        var macAddr = ether_addr()
        guard let macPtr = ether_aton(mac) else { return }
        macAddr = macPtr.pointee
        
        var ipAddr = in_addr()
        inet_pton(AF_INET, ip, &ipAddr)
        
        // This tells the kernel's DHCP server: "If you see this MAC, give it this IP"
       let status = vmnet_network_configuration_add_dhcp_reservation(config, &macAddr, &ipAddr)
        
        if status != .VMNET_SUCCESS {
            print("dhcp faliure \(status.rawValue)")
        }
    }
}

For the first virtual machine the ip address is getting reserved but from second vm onwards ip is not getting reserved it gets from dhcp server. this makes me not able to assign ip address to second virtual machine onwards thus we cant determine the ipadddress of second vm onwards. is there a way we can ask vmnet to refresh the config. is it possible? Or the only way is to create the network config with all the ip address on start of the app and take it from there. what if the user creates a new vm. how to handle this kind of situation. thanks in advance

Ok now i found how to do port forwarding also i used this code

        var ipAddr = in_addr()
        
        // 1. Convert String to in_addr
        inet_pton(AF_INET, guestIP, &ipAddr)
        
        let status = vmnet_network_configuration_add_port_forwarding_rule(
            config,
            UInt8(IPPROTO_TCP),                        // TCP protocol
            sa_family_t(AF_INET),     // address family
            guestPort,                // internal port (guest)
            externalPort,             // external port (host)
            &ipAddr                   // internal address (guest IP)
        )
        
        if status == .VMNET_SUCCESS {
            print("✅ Port Forwarding set: Mac:\(externalPort) -> VM(\(guestIP)):\(guestPort)")
        } else {
            print("❌ Port Forwarding failed for \(guestIP): \(status.rawValue)")
        }
    }

for port forwding it is returning success but when i test it it does not work. Is there anything i am doing wrong? Please help me also in fixing this problem

it seem to be that VZVmnetNetworkDeviceAttachment is only avaialble for mac os 26

Right. I don’t see a good option for earlier systems.

Internally we bounced around the idea of looking for a record of the VM’s MAC address in the ARP cache but, honestly, I’m not a fan of that idea. It’s easy to imagine various ways it might go wrong.

i would like to do the port forwarding.

It looks like you’re making progress on that. If you get completely stuck, I recommend that you start a new thread so that we can keep this thread focused on the IP address issue. Use the same subtopic and tags as this thread; that way I’ll be sure to see it go by.

Coming back to your IP address issue, it seems like you’re trying to share a vmnet interface between all your VMs. I think that’ll work in general, but it presents a problem for this case because you can’t dynamically update the interface’s configuration. The alternative is to allocate a new vmnet interface for each of your VMs. Is there something preventing you from doing that?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Coming back to your IP address issue,

Sorry i was confused between network and interface how to create a new interface should i use this https://developer.apple.com/documentation/vmnet/vmnet_interface_start_with_network(::::) ?

I tried creating new vmnet config and vmnet network for the second vm with same subnet and it failed. It seems to be we cant use the same subnet for new vmnet network. if i provide different subnet it is working fine. But i dont want to have a different subnet for each vm. I think we cant use vmnet_interfce_start_with_network because this is being taken care by the mac os virtuliaztion framewoth with the network we provide. any how i tried this it crashes with bad acces

Programmatic IP Discovery for VZVirtualMachine in an App Store Sandbox
 
 
Q