infusion / node-dhcp

A DHCP server and client written in pure JavaScript
https://raw.org/article/a-pure-javascript-dhcp-implementation/
MIT License
297 stars 75 forks source link

dhcp-proxy #21

Open pieroproietti opened 6 years ago

pieroproietti commented 6 years ago

dhcp-proxy

dhcp-proxy is useful when we need to implement a boot server in a LAN with a pre-existant server dhcp (the majority of uses cases)

This issue

I followed this PXE specification to write this document

Services involved

Use cases

That happen with two server dhcp + dhcp-proxy

PXE-CLIENT -> DHCP       (DHCP Discover to port 67 Contains “PXEClient” extension)
DHCP       -> PXE-CLIENT (DHCP Offer to port 68 Contains [other DHCP option tags] + Client IP addr)
PXE-CLIENT -> DHCP       (DHCP Request to port 67)
DHCP       -> PXE-CLIENT (DHCP Ack to port 68)

PXE-CLIENT -> DHCP-PROXY (Discover to port 67 Contains “PXEClient” extension) * initial DHCPREQUEST
DHCP-PROXY -> PXE-CLIENT (DHCP Offer to port 68 Client IP addr set to 0.0.0.0)
PXE-CLIENT -> DHCP-PROXY (DHCP Request to port 4011 Contains “PXEClient” extension)
DHCP-PROXY -> PXE-CLIENT (DHCP Ack reply to port client’s port Contains “PXEClient” extension tags + pxelinux.0 file)

PXE-CLIENT -> TFTP       (pxelinux.0 download request to TFTP port 69 or MTFTP port assigned in DHCP Ack w/ pxelinux.0 file)
TFTP       -> PXE-CLIENT (pxelinux.0 download to client’s port)

The PXE client knows to interrogate the Proxy DHCP service because the DHCPOFFER from the DHCP service contains an Option #60 “PXEClient” tag without corresponding Option #43 tags or a boot file name

Code

Variables involved

Code

options.js

93: {
  name: 'Client system architecture.',
  type: 'UInt8',
  enum: {
    0: 'IA_X86_PC',
    1: 'NEC98_PC',
    2: 'IA_64_PC',
    3: 'ALPHA',
    4: 'ARC_X86',
    5: `INTEL_LEAN_CLIENT`
  },
  attr: 'csa'
},

examples/proxy.js

This is just an example, I introduced the variables dhcpProxy and req.csa (client system architecture)

var dhcpd = require('../lib/dhcp.js');

var p = dhcpd.createServer({
dhcpProxy: true,
range: [
  "192.168.3.10", "192.168.3.99"
],
server: '192.168.3.2', // This is bootserver
bootFile: function (req, res) {
  if (req.csa === '0') {
    return 'x86linux.0';
  } else {
    return 'x64linux.0';
  }
}
});

p.on('message', function (data) {
  console.log(data);
});

p.on('bound', function(state) {
  console.log("BOUND:");
  console.log(state);
});

p.on("error", function (err, data) {
  console.log(err, data);
});

s.on("listening", function (sock) {
  var address = sock.address();
  console.info('Server Listening: ' + address.address + ':' + address.port);
});

p.on("close", function () {
  console.log('close');
});

p.listen();

process.on('SIGINT', () => {
    p.close();
});
wideblue commented 4 years ago

Regarding option 93, there are more system architectures now. Relevant stackoverflow answer