TUN/TAP subnet: Using DHCP/IPv4

This section relies on the value of a variable named CURTUNTP, with the assumption that the CURTUNTP variable was set by some prior instructions. (If setting that variable is problematic, you could just specify the TUN/TAP name directly. Naturally, that interface name should be customized as these directions are followed.) Use the actual TUN/TAP interface name that the virtual machine is configured to use.

echo ${CURTUNTP}

This guide is designed around the use of ISC DHCP, or similar. (ISC DHCP is the name of a product, the Internet Software Consortium's DHCP server. OpenBSD's DHCP is based on some older ISC DHCP code.)

Using example

Editing an example may be nicer than trying to create the file from scratch. Find the example configuration file.

find /etc/ -iname "*dhcpd*.conf"

Copy that “example” configuration file.

Note that, in this example, the filename contains a reference to the name of the NIC that will be receiving the DHCP traffic. On a system with multiple NICs, where presumably there may be multiple DHCP configurations (including the possibility that a NIC might be configured to not use DHCP), using the NIC name as part of the filename is a good idea. However, that is not required at all.

On systems with multiple NICs, there may be a desire to listen to just one NIC, or perhaps multiple NICs but not all. If listening to just one NIC, it can be nice to specify which NIC is being listened to. (The following example is intended to be customized.)

echo n|sudo -n cp -p -i /etc/examples/dhcpd.conf /etc/dhcpd-${CURTUNTP}.conf

By now, you have a need to know what address should be assigned. (If such decisions haven't already been made yet, then, by all means, make them.)

Customize the name of the NIC in the following example:

echo ${VISUAL}
sudoedit /etc/dhcpd-${CURTUNTP}.conf

Many of the lines in the original example file (e.g.: OpenBSD CVSWeb: /etc/examples/dhcpd.conf) are unneeded. Adjust the example as needed, or add new lines as needed, so that the file looks like this:

option domain-name "sample.example.zz";
# Above list contains OpenDNS and GoogleDNS.  More addresses @ CyberPillar.com
# at /dirsver/1/mainsite/techns/netwrkin/netistrc/namtoadr/dns/dns.htm#dnsdusbl

subnet netmask {
option routers;



The “option routers line specifies the “default gateway”. It must be within the specified subnet. The information on the “subnet” line intentionally matches the information on the network interface. The range is also supposed to be entirely within the subnet.

To test: Clearly the fixed-address should be in the subnet. I believe that it must be outside of any range. (That is unlike the DNS server built into the “Server” versions of Microsoft Windows, which requires that a range does include the fixed-address line. This is simply an example of different software using different rules about how the software is set up.)

Some customization is going to be needed here.

Subnet mask

To determine the subnet mask to use for an IPv4 subnet that is a /24 or smaller subnet (meaning that the number after the slash is bigger), looking at the last (lowest) box of a VLSM Chart may be helpful.

If you're not yet familiar with subnetting (subnetting), then simply know that is very common because it is relatively easy to use, and is a pretty good and safe general recommendation, although is more specific to point-to-point links. If it is known that only two devices will ever be on this subnet, then is a preferred netmask.


The “sample.example.zz” is a domain name that is meant to be customized. It may be a sub-domain of a public domain (looking something like “myproject.example.net”.

Of particular note: do not use a domain name ending with “.local”. Many technicians may have been trained to do so, with the belief that there may be some advantage to using a non-public domain, and under the mistaken belief that “.local” would never be used for anything else, particularly since many people have used “.local” as part of implementations of Microsoft's Active Directory. Well, that didn't end up being true (thanks to RFC 6762, which was written by a couple of Apple employees). There is now an RFC that assigns a use to “.local” (perhaps thanks to Apple). The best approach, easiest to be recommended, is probably to just avoid that particular toxic domain.

If you want a private domain, ending with .zz may be an option. For instance, if the physical box has a variable named VMGenNam with a value of “mylocal”, then using a domain of "mylocal.zz" may work. Although this technique is not from a publicly posted IETF RFC document, at least using .zz is backed by a recognized standards organization, as noted by: DNS Reserved (which mentions “ZZ”). Or, if there is some reason to prefer using a choice other than .zz, other options include .aa or any two-letter combination starting with .q or .x (as also noted by DNS Reserved).


Getting fancy

If you'd like to use the MAC-48 address, you can do so. This sample shows a “range” line, but that is commented out, so it has no impact.

option domain-name "sample.example.zz";
# Above list contains OpenDNS and GoogleDNS.  More addresses @ CyberPillar.com
# at /dirsver/1/mainsite/techns/netwrkin/netistrc/namtoadr/dns/dns.htm#dnsdusbl (DNS Usable)

subnet netmask {
# option routers;


host static-client {
# device identifying address (MAC-48)
hardware ethernet 52:54:00:12:11:01;
# VMNUM is fifth hexadec' pair^^

# device IPv4 address

# default gateway
option routers;

The fixed-address will need to be within the specified subnet. (When that is true, then the first bits of the address will be identical. It is, therefore, common to see part of the address looking like it starts the same.) Otherwise, dhcpd will refuse to hand out the static address (but it will run, and will not complain with an error message).

NIC must listen

Before successfully starting the DHCP/IPv4 server, the NIC that will be receiving the DHCP/IPv4 traffic must be ready to listen for traffic. If that NIC does not yet have its IPv4 set, then fix that before trying to run the server.

Run the server

Then, try running the server. Note that in this example, which includes the interface name as part of the filename, the name of the TUN/TAP device shows up twice in a single command line. (If you are not using the variable shown by this guide, make sure to customize both locations.)

sudo dhcpd -c /etc/dhcpd-${CURTUNTP}.conf ${CURTUNTP}
echo ${?}
ps -auxww | grep -i dhcpd
sudo tail /var/log/messages
Some notes about using ps

Note that although the above syntax will work okay with OpenBSD, ps syntax differences are significant enough that no single syntax is preferred by all the Unix implementations. Users of other operating systems may need to adjust the example shown. (Common modifications may include taking out the hyphen right after the word ps and/or removing some parameters, such as one or both of the w characters.)

Multiple redirections are shown. The final redirection is discussed in the section about “Having grep exclude itself”.

dhcpd -n -c /etc/dhcpd-${CURTUNTP}.conf
echo ${?}

If the configuration file is valid, then dhcpd outputs no text, and the echo command will output a zero. If there a configuration error detected, then the echo command will output a one. Even better yet, the dhcpd will likely report the problem.

If the expected dhcpd is not running, check for error messages. (The program might not be considerate enough to provide a “verbose” option.)

tail /var/log/daemon | grep -i dhcpd
tail /var/log/messages | grep -i dhcpd

Note: The above commands are designed for a not-very-busy server. If other programs are likely to be writing to the log file, then some additional care may be needed to view the messages.

If this is not the first attempt to run the server, then pay attention to the number in the square braces right after the word “dhcpd”. That is a PID, and so it should presumably change each time you run the program. If you're not seeing the number change, you might be looking at older messages. You can also pay attention to the time stamp, if that helps any.

Optional: Some people might want to run “ tail -f /var/log/messages ” in another terminal. Then, after making changes to the text file, press the Enter key a few times so that new messages are easily visually distinct from older messages. Finally, the command can be exited with Ctrl-C. This is a very optional step that some people like to do, but people should not worry about this too much if there's some challenge/difficulty (such as if there is no terminal multiplexer, and so getting a second terminal would be a challenge).