DHCP implementation in... PHP

December 12, 2016 by Paulina BudzoƄ

PHP is not usually used to implement network services - and generally for good reasons. Not because it can’t be done, but rather because it’s not what it was meant to be used for. Although, if you think that PHP simply can’t be used for anything other than serving your blog, think again. Because my DHCP implementation in PHP seems to work quite well!

Yes, DHCP in PHP. If you’re asking WHY?!, the answer is simple: to show it can be done and to learn. This was not meant to be used for anything production-related or anything other than learning. It may be a good way for PHP developers to explore DHCP protocol, find out how it works and experiment. The code, available on GitHub, is divided into two namespaces:

DHCP - which is a basic representation of a DHCP packet and its options as PHP objects. The class DHCP\DHCPPacket can translate the any binary packet data captured through a network socket into objects. It can also be used to create a completely new packet, set its properties and convert it into a binary data to be sent back over the network.

This can be used to analyse network packets, create DHCP servers and clients. Not all DHCP options are implemented, but they can be easily added by creating an appropriate class inside DHCP\Options

DHCPServer implements a very simple DHCP Server, storing information about leases and clients inside PostgreSQL. It opens standard DHCP ports (67 and 68) for communication and will respond to any DHCPDISCOVER, DHCPREQUEST and DHCPRELEASE packets. It also supports serving static IP addresses from a configured list (inside PostgreSQL) based on client’s MAC address.

This server was tested with dhclient with its standard (minimal) configuration on Red Hat 7 and also with default clients on Windows 7 and MacOS Sierra - all working!

To start the server, install dependencies with composer install, create PostgreSQL tables (see README.md) and run:

php server.php serve x.x.x.x/y password

inside src/DHCPServer/. Replace x.x.x.x/y with IP address and mask you want the server to listen on (for example 10.0.0.1/25 and password with password to PostgreSQL (as said before, this is a very simple and basic implementation).

For a demonstration of the server in action, check out the video:

Limitations

As said before, PHP is not meant to be used to create network services, so it’s not best equipped to deal with them. Because of that (as you may have figured out from the examples above), it’s not possible for PHP to listen on a specific interface - it can only bind itself to a specific IP or broadcast on all interfaces. That means you cannot have any other DHCP server or client running on the machine as PHP will not be able to open the sockets it needs.

If you’re interested to learn more about DHCP, see those two basic RFCs: RFC 2131 - Dynamic Host Configuration Protocol and RFC 2132 - DHCP Options and BOOTP Vendor Extensions.

Posted in: Networking Web development