node-dhcp
node-dhcp copied to clipboard
dhcp-proxy
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
- DHCP port 67
- DHCP-PROXY port 67 or 4011
- PXE-CLIENT port 68
- TFTP port
Use cases
- One server with DHCP (Not necessary: we can fill the option 67 with id TFPT and option 68 with fileName)
- One server with DHCP and DHCP-PROXY (Not necessary, we can use the default dhcp as before)
- Two servers preesistent with DHCP and other with DHCP-PROXY (the most usefull, probably we can use port 67 alternative port 4011)
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
- csa refer to option 93 // Sent by client to specify their system artchitecture
- tftpserver refer to option 66 // RFC 2132: PXE option
- filename refer to option 67 // RFC 2132: PXE option
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();
});
Regarding option 93, there are more system architectures now. Relevant stackoverflow answer