{"id":13454776,"url":"https://github.com/infusion/node-dhcp","last_synced_at":"2025-04-13T00:49:39.713Z","repository":{"id":49625904,"uuid":"90802768","full_name":"infusion/node-dhcp","owner":"infusion","description":"A DHCP server and client written in pure JavaScript","archived":false,"fork":false,"pushed_at":"2024-03-27T13:48:27.000Z","size":141,"stargazers_count":301,"open_issues_count":32,"forks_count":74,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-04-13T00:49:27.292Z","etag":null,"topics":["dhcp","javascript","node","server"],"latest_commit_sha":null,"homepage":"https://raw.org/article/a-pure-javascript-dhcp-implementation/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/infusion.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-10T00:06:19.000Z","updated_at":"2025-01-03T21:51:52.000Z","dependencies_parsed_at":"2024-10-28T21:46:15.756Z","dependency_job_id":null,"html_url":"https://github.com/infusion/node-dhcp","commit_stats":{"total_commits":114,"total_committers":11,"mean_commits":"10.363636363636363","dds":"0.20175438596491224","last_synced_commit":"6236c0e1cdfb13e1db64b599a8b93c09197a8373"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infusion%2Fnode-dhcp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infusion%2Fnode-dhcp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infusion%2Fnode-dhcp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infusion%2Fnode-dhcp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/infusion","download_url":"https://codeload.github.com/infusion/node-dhcp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248650436,"owners_count":21139672,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dhcp","javascript","node","server"],"created_at":"2024-07-31T08:00:57.860Z","updated_at":"2025-04-13T00:49:39.694Z","avatar_url":"https://github.com/infusion.png","language":"JavaScript","readme":"\n![node-dhcp](https://github.com/infusion/node-dhcp/blob/master/res/logo.png?raw=true \"JavaScript DHCP Server\")\n\n[![NPM Package](https://img.shields.io/npm/v/dhcp.svg?style=flat)](https://npmjs.org/package/dhcp \"View this project on npm\")\n[![Build Status](https://travis-ci.org/infusion/node-dhcp.svg?branch=master)](https://travis-ci.org/infusion/node-dhcp)\n[![MIT license](http://img.shields.io/badge/license-MIT-brightgreen.svg)](http://opensource.org/licenses/MIT)\n\nnode-dhcp is a RFC compliant DHCP client and server implementation on top of node.js.\n\nMotivation\n===\n\nA DHCP server can be used to configure the entire local network. Typical parameters that can be organized with a DHCP server are ip-addresses, gateways / router, DNS server and really a lot more. DHCP is quite old and well establishd solutions are on the market, commercially and open source - so why a new implementation?\n\nI was searching for a minimalistic DHCP server, which is robust and highly configurable. The first problem I had was: I wanted to deliver an IP address to a Raspberry PI without static configuration right out of my Macbook. However, Apple made it almost impossible to configure the onboard DHCP-server with newer versions of OSX.\n\nThe second motivation was this. In times of **home automation** and **IoT**, I was thinking of a solution, which can trigger something when I come home. DHCP is a good idea here, since any device will broadcast to the network, as soon as it connects. So why not playing the imperial march when you come back home?\n\nAnother problem I had was, I wanted to query DHCP servers without actually change the local configuration.\n\nThese problems were the trigger to start reading the RFC's and the protocol is really not that complicated. As such, this project was born.\n\nRemark: By nature, network services are quite complex, so please test, test, test!\n\nUsage\n===\n\nCommand line\n---\n\nWhen installed globally, node-dhcp provides two executables, a client `dhcp` and a server `dhcpd`. The client simply retrieves network configuration from a DHCP server and prints the configuration after a complete handshake. All additional (defined in `lib/options.js`) fields can be specified as list of arguments:\n\n```bash\n# sudo dhcp hostname [--mac 12:23:34:45:56:67]\n\noutput:\nnetmask :  255.255.255.0\nrouter :  192.168.1.1\ndns :  8.8.8.8, 8.8.4.4\nserver :  192.168.1.1\nhostname :  web392\n```\n\nOn the other hand, the server can be used to provide the data:\n\n```bash\nsudo dhcpd --range 192.168.1.2-192.168.1.99 --hostname web392 --server 192.168.1.1 --router 192.168.1.1\n```\n\nAll available options can be found in `lib/options.js`. The more powerful interface however, is the JavaScript API.\n\nSimple DHCP Server\n---\n\n```js\nvar dhcp = require('dhcp');\n\nvar s = dhcp.createServer({\n  // System settings\n  range: [\n    \"192.168.3.10\", \"192.168.3.99\"\n  ],\n  forceOptions: ['hostname'], // Options that need to be sent, even if they were not requested\n  randomIP: true, // Get random new IP from pool instead of keeping one ip\n  static: {\n    \"11:22:33:44:55:66\": \"192.168.3.100\"\n  },\n\n  // Option settings (there are MUCH more)\n  netmask: '255.255.255.0',\n  router: [\n    '192.168.0.1'\n  ],\n  dns: [\"8.8.8.8\", \"8.8.4.4\"],\n  hostname: \"kacknup\",\n  broadcast: '192.168.0.255',\n  server: '192.168.0.1', // This is us\n  bootFile: function (req, res) {\n\n    // res.ip - the actual ip allocated for the client\n\n    if (req.clientId === 'foo bar') {\n      return 'x86linux.0';\n    } else {\n      return 'x64linux.0';\n    }\n  }\n});\n\ns.listen();\n```\n\nAny config directive can be a function, like illustrated with the bootFile directive for PXE boot. This way you get a fully programable DHCP server.\n\nSimple DHCP Client\n---\n\n```js\nvar dhcp = require('dhcp');\n\nvar s = dhcp.createClient();\n\ns.on('bound', function (state) {\n\n  console.log(\"State: \", state);\n\n  // Configure your host system, based on the current state:\n  // `ip address add IP/MASK dev eth0`\n  // `echo HOSTNAME \u003e /etc/hostname \u0026\u0026 hostname HOSTNAME`\n  // `ip route add default via 192.168.1.254`\n  // `sysctl -w net.inet.ip.forwarding=1`\n\n});\n\ns.listen();\n\ns.sendDiscover();\n```\n\nSniff DHCP Traffic\n---\n\nFor research purposes it's also possible to just get triggered when broadcast events occur. This way an own DHCP server can be implemented. It's also possible to just listen to the traffic on the network, without answering. This can be used to automate something when a device enters the network (you come back home from work and your mobile phone gets into wifi) or to spot malicious DHCP servers on the network:\n\n```js\nvar dhcp = require('dhcp');\n\nvar s = dhcp.createBroadcastHandler();\n\ns.on('message', function (data) {\n\n  if (data.options[53] === dhcp.DHCPDISCOVER) {\n    if (data.chaddr === '12-34-56-78-90-AB') {\n      console.log('Welcome home!');\n    }\n  }\n});\n\ns.listen();\n```\n\nDocker\n===\n\nQuick test\n---\n\n```bash\n# Build the image\ndocker build -t infusion/node-dhcp:0 .\n# Start the server\ndocker run -d --name dhcpd infusion/node-dhcp:0\n# Start a client in the container (and send process to background)\ndocker exec dhcpd dhcp hostname --mac 12:23:34:45:56:67 \u0026\n# Show the server logs\ndocker logs dhcpd\n```\n\nConfiguration assuming Host broadcast\n---\n\nAssuming the dhcp server is on a broadcast network:\n\n```bash\n# Build the image\ndocker build -t infusion/node-dhcp:0 .\n# Start the server\ndocker run --net=host -d --name dhcpd infusion/node-dhcp:0\n```\n\nConfiguration assuming router DHCP relay\n---\n\nAssuming a router is relaying DHCP to multiple IP addresses on server host:\n\n```bash\n# Build the image\ndocker build -t infusion/node-dhcp:0 .\n# Start the servers\ndocker run -p the.host.ip:67:67/udp -d --name dhcpd1 infusion/node-dhcp:0\ndocker run -p other.host.ip:67:67/udp -d --name dhcpd2 infusion/node-dhcp:0\n```\n\nInstallation\n===\n\nInstalling node-dhcp is as easy as cloning this repo or use npmjs:\n\n```bash\nnpm install dhcp\n```\n\nIf command line tools `dhcp` and `dhcpd` shall be installed, npmjs can be used as well:\n\n```bash\nnpm install dhcp -g\n```\n\n\nConfiguration\n===\n\nBesides options listed in the `lib/options.js` file (with the `config` key), a few global options can be used:\n\n- `range`: Two element array, representing the IP range the server operates on\n- `forceOptions`: Array of options that are forced to be sent\n- `static`: A static IP binding object of the form `mac -\u003e ip`\n\nNot yet implemented features\n===\n\nnode-dhcp does not set timers already on the client to periodically send RENEW or REBIND messages. If you need this feature, please file a bug ticket.\n\nTroubleshooting\n===\n\nEACCESS Error\n---\n\nSince the programs need to bind to port 67 and 68, root privileges are required. If you want to use dhcp and dhcpd without root privileges, change the port to something above 1024.\n\nNo data is received\n---\n\nA broadcast is typically not spread across all interfaces. In order to route the broadcast to a specific interface, you can reroute 255.255.255.255.\n\nLinux\n---\n\n```bash\nroute add -host 255.255.255.255 dev eth0\n```\n\nOS-X\n---\n\n```bash\nsudo route add -host 255.255.255.255 -interface en4\n```\n\nDHCP Options\n---\n\nA wide range of options are already implemented. Custom options can be defined with\n\n```js\nconst dhcpd = require(\"dhcp\")\ndhcpd.addOption(123, {\nconfig: \"testConfig\",\ntype: \"ASCII\",\nname: \"Test Option\"\n});\n```\n\nTesting\n===\n\nIf you plan to enhance the library, make sure you add test cases and all the previous tests are passing. You can test the library with\n\n```bash\nnpm test\n```\n\nCopyright and licensing\n===\n\nCopyright (c) 2017-2022, [Robert Eisele](https://raw.org/)\nLicensed under the MIT license.\n","funding_links":[],"categories":["Packages","JavaScript","Repository","包","Fingerprint","Network","目录"],"sub_categories":["Network","网络","DHCP"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finfusion%2Fnode-dhcp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finfusion%2Fnode-dhcp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finfusion%2Fnode-dhcp/lists"}