MAC Address Matching for the ISC DHCP server

I frequently use the ISC DHCP server software at customer sites. I enjoy using this software because it is simple, powerful, and reliable. Recently I had need to assign a large number of IP phones to a specific subnet via an ISC DHCP server.  We were able to obtain the MAC address prefix that was unique to each of our various types of IP phones.  Hunting around on the web, I found several posts discussing how to configure the DHCP server, but in retrospect, none of them seem to have it exactly right.  So here's my take on how this should be done.

The technique directly examines the portion of the MAC address that is common for each model of phone.  For example, say we have MAC addresses for our phones such as:

00:01:02:03:??:??

Since the first several octets of the MAC address are the same, we'll need to configure the DHCP server to detect any MAC addresses which match this pattern, and return an appropriate IP address.

To do this, we need to understand what "hardware" addresses the DHCP server detects.  In conforming to the DHCP protocol, the client prefixes the MAC address with the media type, in this case Ethernet, type "01". As a result, the complete hardware address the DHCP server will "see" will be:

01:00:01:02:03:??:??

where the added "01" at the start of the address indicates an Ethernet MAC address.

Several schemes I saw during my research involved converting this hardware address to a text string, and then trying to compare the text string values.  While that technique works, I find it cumbersome and potentially unreliable - you have to match against the "short" versions of the MAC addresses if the octet has a leading 0.  So using the text string technique we would have to compare to "1:0:1:2:3".

Because of this limitation, I like to leave the hardware address as a binary value, and compare to it directly.  While this may sound complex, it's actually quite simple:

class "Phones" {
  match if (substring(hardware, 0, 5) = 01:00:01:02:03);
}

In the above example, notice the MAC address is specified WITHOUT QUOTES - it is not text! As a result, it can also be specified either using the two-character octets as shown, or using the short version - either works! This is because values specified outside of quotes in the dhcpd.conf configuration file are interpreted as literals - and not text.

Also notice that I do my substring comparison starting at offset 0, and that I specify my MAC address prefix with the hardware type included.  This ensures that the MAC address will be properly matched if other hardware types (besides Ethernet) exist in your environment.  If your environment is (and will be) purely Ethernet, then it is valid to compare just the MAC address portion:

match if (substring(hardware, 1, 4) = 00:01:02:03);

To then hand out a range of addresses to the matching devices, you would create a pool, and allow access by members of the class, as shown in the following example:

subnet 10.0.0.0 netmask 255.255.0.0 {
  option routers 10.0.0.1;

  pool {
    range 10.0.1.0 10.0.1.255;
    allow members of "Phones";
  }

  # Other pools ... 
}

This limits allows our IP phones to receive addresses in the range 10.0.1.0-10.0.1.255, keeping them apart from our other clients!

In future articles, I'll show how to use a similar technique to create a pool for several different models of IP phones, and also specific DHCP setup information for Avaya IP phones.

Comments

This is the only doc on the web that I have found that describes the hardware type and offset intelligently. Thanks and keep up the good work.

I wrote this article several years ago, but still use that technique to this day.  Glad it helped you out Chris!

Helped me understand easily. The best explanation on the web relating to this topic.