Comparing version 0.1.0 to 0.2.0
192
lib/dhcp.js
@@ -21,4 +21,4 @@ | ||
const SERVER_PORT = 2004;//67; | ||
const CLIENT_PORT = 2005;//68; | ||
const SERVER_PORT = 67; | ||
const CLIENT_PORT = 68; | ||
@@ -58,3 +58,3 @@ const INADDR_ANY = '0.0.0.0'; | ||
sock.on('message', function (buf) { | ||
sock.on('message', function(buf) { | ||
@@ -88,3 +88,3 @@ var req = Protocol.parse(buf); | ||
sock.on('listening', function () { | ||
sock.on('listening', function() { | ||
self.emit('listening', sock); | ||
@@ -111,3 +111,3 @@ }); | ||
config: function (key) { | ||
config: function(key) { | ||
@@ -153,3 +153,3 @@ var val; | ||
}, | ||
_getOptions: function (pre, required, requested) { | ||
_getOptions: function(pre, required, requested) { | ||
@@ -199,18 +199,110 @@ for (var req of required) { | ||
}, | ||
_selectAddress: function() { | ||
// TODO: | ||
// 1. choose IP | ||
// 2. prefer user wish | ||
// 3. check ARP if IP exists | ||
return '192.168.1.26'; | ||
_selectAddress: function(clientMAC) { | ||
/* | ||
* IP Selection algorithm: | ||
* | ||
* 0. Is Mac already known, send same IP of known lease | ||
* | ||
* 1. Is there a wish for static binding? | ||
* | ||
* 2. Are all available IP's occupied? | ||
* - Send release to oldest lease and reuse | ||
* | ||
* 3. is config randomIP? | ||
* - Select random IP of range, until no occupied slot is found | ||
* | ||
* 4. Take first unmapped IP of range | ||
* | ||
* TODO: | ||
* - Incorporate user preference, sent to us | ||
* - Check APR if IP exists on net | ||
*/ | ||
// If existing lease for a mac address is present, re-use the IP | ||
if (this._state[clientMAC] && this._state[clientMAC].address) { | ||
return this._state[clientMAC].address; | ||
} | ||
// Is there a static binding? | ||
var static = this.config('static'); | ||
if (static[clientMAC]) { | ||
return static[clientMAC]; | ||
} | ||
var randIP = this.config('randomIP'); | ||
var _tmp = this.config('range'); | ||
var firstIP = Tools.parseIp(_tmp[0]); | ||
var lastIP = Tools.parseIp(_tmp[1]); | ||
// Add all known addresses and save the oldest lease | ||
var ips = [this.config('server')]; // Exclude our own server IP from pool | ||
var oldestMac = null; | ||
var oldestTime = Infinity; | ||
var leases = 0; | ||
for (var mac in this._state) { | ||
if (this._state[mac].address) | ||
ips.push(this._state[mac].address); | ||
if (this._state[mac].leaseTime < oldestTime) { | ||
oldestTime = this._state[mac].leaseTime; | ||
oldestMac = mac; | ||
} | ||
leases++; | ||
} | ||
// Check if all IP's are used and delete the oldest | ||
if (lastIP - firstIP === leases) { | ||
var ip = this._state[oldestMac].address; | ||
// TODO: Notify deleted client | ||
delete this._state[oldestMac]; | ||
return ip; | ||
} | ||
// Select a random IP, maybe not the best algorithm for quick selection if lots of ip's are given: TODO | ||
if (randIP) { | ||
while (1) { | ||
var ip = Tools.formatIp(firstIP + Math.random() * (lastIP - firstIP + 1) | 0); | ||
if (ips.indexOf(ip) === -1) { | ||
return ip; | ||
} | ||
} | ||
} | ||
// Choose first free IP in subnet | ||
for (var i = firstIP; i <= lastIP; i++) { | ||
var ip = Tools.formatIp(i); | ||
if (ips.indexOf(ip) === -1) { | ||
return ip; | ||
} | ||
} | ||
}, | ||
handleDiscover: function (req) { | ||
handleDiscover: function(req) { | ||
console.log('Handle Discover', req); | ||
var lease = this._state[req.chaddr] = this._state[req.chaddr] || new Lease; | ||
lease.address = this._selectAddress(); | ||
lease.address = this._selectAddress(req.chaddr); | ||
lease.leasePeriod = this.config('leaseTime'); | ||
@@ -222,3 +314,3 @@ lease.server = this.config('server'); | ||
}, | ||
sendOffer: function (req) { | ||
sendOffer: function(req) { | ||
@@ -237,3 +329,3 @@ console.log('Send Offer'); | ||
ciaddr: INADDR_ANY, | ||
yiaddr: this._selectAddress(), // My offer | ||
yiaddr: this._selectAddress(req.chaddr), // My offer | ||
siaddr: this.config('server'), // next server in bootstrap. That's us | ||
@@ -257,7 +349,7 @@ giaddr: req.giaddr, | ||
handleRequest: function (req) { | ||
handleRequest: function(req) { | ||
console.log('Handle Request', req); | ||
var lease = this._state[req.chaddr] = this._state[req.chaddr] || new Lease; | ||
lease.address = this._selectAddress(); | ||
lease.address = this._selectAddress(req.chaddr); | ||
lease.leasePeriod = this.config('leaseTime'); | ||
@@ -270,3 +362,3 @@ lease.server = this.config('server'); | ||
}, | ||
sendAck: function (req) { | ||
sendAck: function(req) { | ||
console.log('Send ACK'); | ||
@@ -283,3 +375,3 @@ // Formulate the response object | ||
ciaddr: req.ciaddr, | ||
yiaddr: this._selectAddress(), // my offer | ||
yiaddr: this._selectAddress(req.chaddr), // my offer | ||
siaddr: this.config('server'), // server ip, that's us | ||
@@ -303,3 +395,3 @@ giaddr: req.giaddr, // 'giaddr' from client DHCPREQUEST message | ||
}, | ||
sendNak: function (req) { | ||
sendNak: function(req) { | ||
console.log('Send NAK'); | ||
@@ -333,15 +425,15 @@ // Formulate the response object | ||
handleRelease: function () { | ||
handleRelease: function() { | ||
}, | ||
handleRenew: function () { | ||
handleRenew: function() { | ||
// Send ack | ||
}, | ||
listen: function (port, host, fn) { | ||
listen: function(port, host, fn) { | ||
var sock = this._sock; | ||
sock.bind(port || SERVER_PORT, host || INADDR_ANY, function () { | ||
sock.bind(port || SERVER_PORT, host || INADDR_ANY, function() { | ||
sock.setBroadcast(true); | ||
@@ -354,7 +446,7 @@ if (fn instanceof Function) { | ||
_send: function (host, data) { | ||
_send: function(host, data) { | ||
var sb = Protocol.format(data); | ||
this._sock.send(sb._data, 0, sb._w, CLIENT_PORT, host, function (err, bytes) { | ||
this._sock.send(sb._data, 0, sb._w, CLIENT_PORT, host, function(err, bytes) { | ||
if (err) { | ||
@@ -384,3 +476,3 @@ console.log(err); | ||
sock.on('message', function (buf) { | ||
sock.on('message', function(buf) { | ||
@@ -413,3 +505,3 @@ var req = Protocol.parse(buf); | ||
sock.on('listening', function () { | ||
sock.on('listening', function() { | ||
self.emit('listening', sock); | ||
@@ -434,3 +526,3 @@ }); | ||
config: function (key) { | ||
config: function(key) { | ||
@@ -498,6 +590,8 @@ if (key === 'mac') { | ||
sendDiscover: function () { | ||
sendDiscover: function() { | ||
console.log('Send Discover'); | ||
var mac = this.config('mac'); | ||
// Formulate the response object | ||
@@ -516,3 +610,3 @@ var ans = { | ||
giaddr: INADDR_ANY, | ||
chaddr: this.config('mac'), | ||
chaddr: mac, | ||
sname: '', // unused | ||
@@ -523,3 +617,3 @@ file: '', // unused | ||
53: DHCPDISCOVER, | ||
61: this.config('mac'), // MAY | ||
61: mac, // MAY | ||
55: this.config('features') // MAY | ||
@@ -539,3 +633,3 @@ // TODO: requested IP optional | ||
}, | ||
handleOffer: function (req) { | ||
handleOffer: function(req) { | ||
console.log('Handle Offer', req); | ||
@@ -556,3 +650,3 @@ | ||
sendRequest: function (req) { | ||
sendRequest: function(req) { | ||
@@ -597,3 +691,3 @@ console.log('Send Request'); | ||
}, | ||
handleAck: function (req) { | ||
handleAck: function(req) { | ||
@@ -675,3 +769,3 @@ if (req.options[53] === DHCPACK) { | ||
sendRelease: function (req) { | ||
sendRelease: function(req) { | ||
@@ -713,3 +807,3 @@ console.log('Send Release'); | ||
sendRenew: function () { | ||
sendRenew: function() { | ||
@@ -751,3 +845,3 @@ console.log('Send Renew'); | ||
sendRebind: function () { | ||
sendRebind: function() { | ||
@@ -791,7 +885,7 @@ console.log('Send Rebind'); | ||
listen: function (port, host, fn) { | ||
listen: function(port, host, fn) { | ||
var sock = this._sock; | ||
sock.bind(port || CLIENT_PORT, host || INADDR_ANY, function () { | ||
sock.bind(port || CLIENT_PORT, host || INADDR_ANY, function() { | ||
sock.setBroadcast(true); | ||
@@ -804,7 +898,7 @@ if (fn instanceof Function) { | ||
_send: function (host, data) { | ||
_send: function(host, data) { | ||
var sb = Protocol.format(data); | ||
this._sock.send(sb._data, 0, sb._w, SERVER_PORT, host, function (err, bytes) { | ||
this._sock.send(sb._data, 0, sb._w, SERVER_PORT, host, function(err, bytes) { | ||
if (err) { | ||
@@ -824,9 +918,9 @@ console.log(err); | ||
module.exports = { | ||
createServer: function (opt) { | ||
createServer: function(opt) { | ||
return new Server(opt); | ||
}, | ||
createClient: function (opt) { | ||
createClient: function(opt) { | ||
return new Client(opt); | ||
}, | ||
createBroadcastHandler: function () { | ||
createBroadcastHandler: function() { | ||
return new Server(null, true); | ||
@@ -833,0 +927,0 @@ }, |
{ | ||
"name": "dhcp", | ||
"title": "dhcp", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"homepage": "https://github.com/infusion/node-dhcp", | ||
@@ -6,0 +6,0 @@ "bugs": "https://github.com/infusion/node-dhcp/issues", |
@@ -34,2 +34,3 @@ | ||
// output: | ||
// netmask : 255.255.255.0 | ||
@@ -113,3 +114,3 @@ // router : 192.168.1.1 | ||
For 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: | ||
For 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: | ||
@@ -116,0 +117,0 @@ ```js |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
70586
2022
196
1