Configuring a DHCP server to hand out IP addresses is probably one of the most fundamental skills a network engineer could have. Don’t be fooled, however, there is plenty of complexity to be had here as well should your environment require it. Occasionally it can be helpful to have a client device receive a static IP address. You can configure this manually or you can allow DHCP to do the work for you.
In my example, we have two printers we would like to statically address to ensure they are always available to a print server without any reliance on a name resolution method. The Subnet in use in this lab is 22.214.171.124 /24. There is already a DHCP pool configured that looks something like this:
ip dhcp pool TEST1 network 126.96.36.199 255.255.255.0 default-router 188.8.131.52 dns-server 184.108.40.206 domain-name technologyordie.com
Next we need to create an origin file that contains the static mappings.
My sample file looks like this:
*time* Jul 21 2017 01:00 PM *version* 2 !IP address Type Hardware address Lease expiration 220.127.116.11 /24 id 01cc.7e8a.b68f.01 1 *end*
In the file you will need the IP address and CIDR notated subnet mask. Next, the “id” keyword followed by an “01” indicating this is an Ethernet client. The mac address of the client is then appended directly to the “01” essentially shifting the “.” notation by two characters. Finally, a value for the lease expiration which doesn’t seem to do anything. The file must contain a “version” indicator as well as the “end” keyword as shown above.
With this file created, you can host it on a tftp server referencing it from there or you can copy it to the router locally for consumption by the dhcp process. In my case I chose to copy it locally and consume the file right from flash on the device. You can see the file referenced by the “origin” command in the new pool configuration below.
ip dhcp pool TEST2 origin file flash:/dhcp.txt default-router 18.104.22.168 dns-server 22.214.171.124 domain-name technologyordie.com
Personally, I always suggest having “debug ip dhcp server events” running when you enter the origin command to confirm the file was read correctly. Small syntactical errors will prevent its import entirely so this step is critical. As you can see my file is consumed without error:
Jul 22 13:30:11.661: DHCPD: reading bindings from flash:/dhcp.txt. Jul 22 13:30:11.664: DHCPD: read 207 / 1024 bytes. Jul 22 13:30:11.664: DHCPD: parsing text line "*time* Jul 21 2017 01:00 PM" Jul 22 13:30:11.665: DHCPD: parsing text line "*version* 2" Jul 22 13:30:11.665: DHCPD: route: Parsed version = 2 Jul 22 13:30:11.665: DHCPD: parsing text line "!IP address Type Hardware address Lease expiration" Jul 22 13:30:11.665: DHCPD: parsing text line "126.96.36.199 /24 id 01cc.7e8a.b68f.01 15" Jul 22 13:30:11.665: DHCPD: creating binding for 188.8.131.52 Jul 22 13:30:11.665: DHCPD: Allocated binding FF9AF39A70 Jul 22 13:30:11.665: DHCPD: Adding binding to radix tree (184.108.40.206) Jul 22 13:30:11.666: DHCPD: Adding binding to hash tree FF9AF39A70 Jul 22 13:30:11.667: DHCPD: parsing text line "*end*" Jul 22 13:30:11.667: DHCPD: read static bindings from flash:/dhcp.txt.
You may be asking yourself how I can have two overlapping pools without IP addressing conflicts. That’s certainly a very critical question. To get the answer let’s take a look at the DHCP pools with the “show ip dhcp pool” command:
CORE-SW1#show ip dhcp pool | section TEST Pool TEST1 : Utilization mark (high/low) : 100 / 0 Subnet size (first/next) : 0 / 0 Total addresses : 254 Leased addresses : 0 Excluded addresses : 2 Pending event : none 1 subnet is currently in the pool : Current index IP address range Leased/Excluded/Total 220.127.116.11 18.104.22.168 - 22.214.171.124 0 / 1 / 254 Pool TEST2 : Utilization mark (high/low) : 100 / 0 Subnet size (first/next) : 0 / 0 Total addresses : 1 Leased addresses : 1 Excluded addresses : 1 Pending event : none 0 subnet is currently in the pool : Current index IP address range Leased/Excluded/Total 126.96.36.199 188.8.131.52 - 184.108.40.206 1 / 1 / 1
The first pool is showing the full IP address range of the subnet but is listing 1 address exclusion. In the next pool we then see the address causing that exclusion. Essentially, the static pool enters exclusions overwriting the fully dynamic pool to prevent the conflicts.