Robert Eisele
Engineer, Systems Architect and DBA

A pure JavaScript DHCP implementation

When people connect to a WIFI to get internet access, they expect everything to work out of the box. This works because a new client on a network gets configured via the DHCP protocol. Most local routers have DHCP servers on it to deliver router-, DNS- and IP- information. What most people don't know is, how many options really can be configured with DHCP, as DHCP is expected to do just what is expected of it, without thinking about it anymore.

My journey with DHCP began, when I wanted to configure a Raspberry PI via DHCP, but Apple removed priviliges for accessing configuration files of the native DHCP server (as long as you don't disable System Integration Protection). As Apple will not get any money for a new device anymore, such limitations are sometimes good to get creative. I read the RFC and 9 hours later, my PI was configured using a node.js DHCP implementation. After that, I realized how much more fun we can have with DHCP.

Set up a DHCP server

Using dhcp.js, you can set up a DHCP server quite easily with:

var dhcpd = require('dhcp');

var s = dhcpd.createServer({
  // System settings
  range: [
    "192.168.3.10", "192.168.3.99"
  ],
  forceOptions: ['hostname'], // Options that need to be sent, even if they were not requested
  static: {
"11:22:33:44:55:66": "192.168.3.100"
}, // Option settings netmask: '255.255.255.0', router: [ '192.168.0.1' ], dns: ["8.8.8.8", "8.8.4.4"], server: '192.168.0.1', // This is us
hostname: function() {return 'foo' + i++; } }); s.listen();

Every option can be a function, which makes the server highly configurable, without nasty config files. You can load the information from a database to configure an entire cluster if you want.

If you install the library globally via npm, you get access to a command line tool, called "dhcpd". Using it, you can provide the same information via your terminal.

Set up a DHCP client

Setting up a DHCP client is equivalently easy. To start the interaction, the client sends a discover package. When the whole handshake is over, an bind-event is triggered, where you can access the state information to configure the machine. By default, no changes are applied to the system, everything must be done within the callback. Some ideas are in the comment:

var dhcp = require('dhcp');

var s = dhcp.createClient();

s.on('bound', function () {

  console.log("State: ", this._state);

  // `ip address add IP/MASK dev eth0`
  // `echo HOSTNAME > /etc/hostname && hostname HOSTNAME`
  // `ip route add default via 192.168.1.254`
  // `sysctl -w net.inet.ip.forwarding=1`

});

s.listen();

s.sendDiscover();

Monitor local DHCP traffic / Home Automation

Since we work on the protocol itself, we can add hooks for every little event happening. For example, imagine you want to spot malicious DHCP servers on your network. You simply need to monitor DHCP-OFFER messages. A much cooler usecase is monitoring for your mobile phone, coming home and entering the network after a workday. What about turning on the lights, the music and your computer at home, when you reach the door?

var dhcp = require('dhcp');

var s = dhcp.createBroadcastHandler();

s.on('message', function (data) {

  if (data.options[53] === dhcp.DHCPDISCOVER) {
    if (data.chaddr === '12-34-56-78-90-AB') {
      console.log('Welcome home!');
    }
  }
});

s.listen();

I think there is nothing left to say. Install the dhcp package and have fun exploring the new possibilities!

You might also be interested in the following

 

Sorry, comments are closed for this article. Contact me if you want to leave a note.