Controlling DHCP for VMWare Fusion VMs

Published 22:42 on 08 March, 2010

This week I built a brand new Mac for work. This meant I also needed to install VMWare Fusion and knock up a couple of virtual machines for development. Everything was working as expected until I tried using the same VMs at home, and discovered a complete lack of connectivity to—and within—the VMs, despite having active network and internet access on the host OS. After a little investigation, I discovered the issue:

When I’ve used VMWare Fusion in the past, my VMs have all been assigned IPv4 addresses in the range 172.16.0.0 through 172.31.255.255, via DHCP (the 20-bit block of RFC1918). This has always suited me fine, and has meant I’ve been able to assign host file mapping entries for those IP addresses with relative confidence since the addresses have never changed, even after reboots.

However, on the new Mac, I was surprised to find my VMWare VMs being assigned IPv4 addresses in the range 192.168.0.0 through 192.168.255.255 (the 16-bit block of RFC1918). As you can imagine, this could cause a certain degree of havoc if you’re LAN is also assigning DHCP IP addresses in that range. This is exactly what was happening in my case—and on both my work LAN and my home LAN—so VMWare was having to change the IPs each time I changed network.

To fix this issue, all I needed to do was tell VMWare to use a specific range of IP addresses when assigning DHCP. Unfortunately, VMWare doesn’t make this particularly easy (despite including a handy network configuration script). So here’s what you have to do…

A quick word on VMWare Fusion networking

Before I jump in with the “how to”, let me just take a moment to explain how networking works in VMWare Fusion:

VMWare sets up two network interfaces during installation, plus a bridge from Fusion to your host’s active network interface. The two network interfaces that are configured are “vmnet1”–the host-only network–and “vmnet8”–the NAT network interface. It is the latter of the two that we need to configure for control over VM DHCP.

Resetting the network configuration

Firstly, make sure you have shut down all your VMs (even the headless ones), and that the VMWare GUI isn’t running. We’ll also need to make sure, before we start our configuration, that we’re in a predictable state for all the configuration files used by VMWare. Handily, VMWare Fusion supplies a network interface configuration script that will allow us to do exactly that.

VMWare records a bunch of information–in regard to DHCP and the vmnets–in a file called “locations”. To begin with, we’ll need to delete that file so that it is regenerated later:

$ cd /Library/Application\ Support/VMWare\ Fusion/
$ rm -f locations

Following that, we run the handy configuration Perl script, which will automatically answer it’s own questions with the default answers:

$ sudo ./vmware-config-net.pl

Configuring a NAT network for vmnet8.

'ping' -q -t 10 192.168.119.1 > /dev/null status = 2
The subnet 192.168.119.0/255.255.255.0 appears to be unused.

The file /Library/Application Support/VMware Fusion/vmnet8/dhcpd.conf that this program was about to install already exists. Overwrite? [yes]

The file /var/db/vmware/vmnet-dhcpd-vmnet8.leases that this program was about to install already exists. Overwrite? [yes]

The file /var/db/vmware/vmnet-dhcpd-vmnet8.leases~ that this program was about to install already exists. Overwrite? [yes]

…

I haven’t included all the output here, but it continues on for a while.

Once you have a prompt again, it’s time to restart the network services with these update values (even though they’re not going to be final):

$ sudo ./boot.sh --restart

This will give you a “Shutting down VMware Fusion:” message, followed by a “Starting VMware Fusion:” message.

Once you get your prompt back, make sure the network interfaces have been set up correctly by running the interface configurator:

$ ifconfig

…

vmnet8:	flags=8863 mtu 1500
		inet 192.168.119.1 netmask 0xffffff00 broadcast 192.168.119.255
		ether 00:50:56:c0:00:08
vmnet1: flags=8863 mtu 1500
		inet 172.16.225.1 netmask 0xffffff00 broadcast 172.16.225.255
		ether 00:50:56:c0:00:01

…

You should see something like the above, even if the addresses are slightly different. As long as the vmnet8 and vmnet1 interfaces are showing, we’re up and running again.

Defining your IP range

Remember that “locations” file we junked earlier? That’s where we need to define our IP ranges so that the network configuration script can work its magic. Following our little clean-up, that file should now be nice and simple, and ready for our changes. To do that, you’ll need to edit with root permissions:

$ mate locations

I’m using TextMate, which will prompt me for my admin password when I save the file. If you’re using an editor like vi or vim, you’ll need to sudo:

$ sudo vim locations

The settings you need to define in the locations file are as follows:

VNET_8_HOSTONLY_HOSTADDR
VNET_8_HOSTONLY_NETMASK
VNET_1_HOSTONLY_HOSTADDR
VNET_1_HOSTONLY_NETMASK
VNET_1_HOSTONLY_SUBNET

I defined mine like so, with the third digit matching the vmnet to which it is assigned, just so I have a point of reference if I need it:

…
answer VNET_8_HOSTONLY_HOSTADDR 172.16.8.1
answer VNET_8_HOSTONLY_NETMASK 255.255.255.0
…
answer VNET_1_HOSTONLY_HOSTADDR 172.16.1.1
answer VNET_1_HOSTONLY_NETMASK 255.255.255.0
answer VNET_1_HOSTONLY_SUBNET 172.16.1.0

Once we’ve saved our changes, we simply need to reset the network configuration using the same Perl script as earlier:

$ sudo ./vmware-config-net.pl

Configuring a NAT network for vmnet8.

Configuring a host-only network for vmnet1.

The host-only network is currently configured to use the private subnet 172.16.1.0/255.255.255.0. Do you want to keep these settings? [yes]

Finally, restart VMWare Fusion daemons and reconfigure the network interfaces:

$ sudo ./boot.sh --restart

Once that is complete, VMWare is configured to use your defined range of IP addresses for both its vmnets. You can check this by running the interface configurator again:

$ ifconfig
…
vmnet8: flags=8863 mtu 1500
        inet 172.16.8.1 netmask 0xffffff00 broadcast 172.16.8.255
        ether 00:50:56:c0:00:08 
vmnet1: flags=8863 mtu 1500
        inet 172.16.1.1 netmask 0xffffff00 broadcast 172.16.1.255
        ether 00:50:56:c0:00:01

Summary

So now you can configure your vmnets in VMWare Fusion to use a predictable range of IP addresses. That, as they say, is that.