apaprocki / node-dhcpjs

dhcpjs provides native DHCP support in Node.js
MIT License
61 stars 21 forks source link

Working Client #2

Open groundwater opened 10 years ago

groundwater commented 10 years ago

Hey, I'm very interested in finding a working DHCP client in Node. Correct me if I'm wrong, but the client doesn't actually seem to work.

The project seems to have taken some big steps forward however, can you point me in a direction where I could contribute to getting the client working?

apaprocki commented 10 years ago

What would you want the client to do? Simply negotiate itself a lease and allow you to try to renew it?

If a hypothetical client negotiated successfully, it would simply report the details of its lease as JSON -- it wouldn't be able to actually configure an interface from within Node.

groundwater commented 10 years ago

It just needs to be able to obtain the lease and renew it. A JSON type blob would be perfect.

I have a working, but far from polished module for configuring network interfaces at src-sockios.

I am one DHCP client short of automatically bootstrapping a functional network OS using only Node. I would like to create a dhcp-service module that combines dhcpjs with src-sockios.

apaprocki commented 10 years ago

Not a full solution (yet), but I just added some basic support and an example that sends DHCPDISCOVER and prints the DHCPOFFER replies in example-client.js. I'll work on building that out into something that completes the dance and gets a lease.

piranna commented 9 years ago

What's the current status? I've tried example-client.js on several networks but I don't get any answer at all, so I can't be able to implement a DHCP client... The only output I get both on Ubuntu and NodeOS (the project started by @groundwater and that now I'm maintaining myself) is:

listening on 0.0.0.0:68
bound to 0.0.0.0:68
dhcpDiscover: sent

Shouldn't it give also the response from the DHCP server?

apaprocki commented 9 years ago

Are you running it as root? As a normal user you won't be able to bind to port 68. Also, are you sure nothing else is listening on the port already? You can check using netstat -an.

piranna commented 9 years ago

Yes, I'm executing it as root. If not, it gives a permissions problem, and if the port is being used an ADDRINUSE one El 16/05/2015 23:50, "Andrew Paprocki" notifications@github.com escribió:

Are you running it as root? As a normal user you won't be able to bind to port 68. Also, are you sure nothing else is listening on the port already? You can check using netstat -an.

— Reply to this email directly or view it on GitHub https://github.com/apaprocki/node-dhcpjs/issues/2#issuecomment-102701423 .

apaprocki commented 9 years ago

Silly question -- did you change the chaddr in the example to be the MAC address of your interface?

piranna commented 9 years ago

No, I didn't, I used the package as it got downloaded. Should I change it? If so, maybe it should be fetch automatically... El 17/05/2015 00:41, "Andrew Paprocki" notifications@github.com escribió:

Silly question -- did you change the chaddr in the example to be the MAC address of your interface?

— Reply to this email directly or view it on GitHub https://github.com/apaprocki/node-dhcpjs/issues/2#issuecomment-102707808 .

piranna commented 9 years ago

Don't know if it's v0.12 only, but the build-in os module has a networkInterfaces method that return a list with the available network interfaces, including their MAC address:

> var os = require('os')
undefined
> os.getNetworkInterfaces()
getNetworkInterfaces is now called `os.networkInterfaces`.
{ lo: 
   [ { address: '127.0.0.1',
       netmask: '255.0.0.0',
       family: 'IPv4',
       mac: '00:00:00:00:00:00',
       internal: true },
     { address: '::1',
       netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
       family: 'IPv6',
       mac: '00:00:00:00:00:00',
       scopeid: 0,
       internal: true } ],
  wlan0: 
   [ { address: '192.168.1.184',
       netmask: '255.255.255.0',
       family: 'IPv4',
       mac: '10:9a:dd:b0:c2:c4',
       internal: false },
     { address: 'fe80::129a:ddff:feb0:c2c4',
       netmask: 'ffff:ffff:ffff:ffff::',
       family: 'IPv6',
       mac: '10:9a:dd:b0:c2:c4',
       scopeid: 3,
       internal: false } ] }

This could be used to fetch the MAC address automatically so the example client can work without modifying the code. Only thing that network interfaces must be up (with an IP?) so they can be listed there. Maybe the node-ifconfig command can be modified so it can up the network interfaces without setting an IP address? With a DHCP client an IP address is not necesary at all...

apaprocki commented 9 years ago

Yes, that is what a real DHCP client would do -- only it would have the logic for which network interface to use. The example code in the repository has a dummy MAC address in it because it is just an example. If you'd like to see it working, then just replace the MAC address with the one associated with your wlan0, 10:9a:dd:b0:c2:c4.

piranna commented 9 years ago

I see. Then if it's so simple, for example purposses I think it should use the MAC address of the machine where it's running instead of having a hardcoded one... I'll try to test it and do a pull-request later. Should I modify any other thing? Transaction ID, maybe? bind call?

piranna commented 9 years ago

https://github.com/apaprocki/node-dhcpjs/pull/4

getNetworkInterfaces is now called `os.networkInterfaces`.
listening on 0.0.0.0:68
bound to 0.0.0.0:68
dhcpDiscover (wlan0): sent
dhcpDiscover (wlan0): sent
dhcpOffer: { op: { [Number: 2] value: 2, name: 'BOOTPREPLY' },
  hlen: 6,
  hops: 0,
  xid: 1,
  secs: 0,
  flags: 0,
  ciaddr: undefined,
  yiaddr: '10.1.70.89',
  siaddr: undefined,
  giaddr: undefined,
  chaddr: 
   { type: { [Number: 1] value: 1, name: 'HW_ETHERNET' },
     address: '10:9a:dd:b0:c2:c4' },
  sname: '',
  file: '',
  magic: 1669485411,
  options: 
   { dhcpMessageType: { [Number: 2] value: 2, name: 'DHCPOFFER' },
     serverIdentifier: '1.1.1.1',
     ipAddressLeaseTime: 14400,
     routerOption: [ '10.1.64.1' ],
     domainNameServerOption: [ '193.147.69.2', '193.147.184.11' ],
     domainName: 'urjc.es',
     subnetMask: '255.255.248.0' } }

That's WAY better... :-D So with that info, seems it would be really easy to craft a real DHCP client... :-)

piranna commented 9 years ago

https://github.com/joyent/node/issues/9029 https://github.com/nodejs/io.js/issues/498

Ok, os.networkInterfaces() only show the interfaces that currently hold an IP address, although they are fixing it to show all of them by using a flag on the method. There's a workaround reading /proc or /sys, though.

apaprocki commented 9 years ago

The front-end Node/io.js issues are just fronts for the change, which would have to happen in libuv. The relevant issue/pull request in libuv appear to be:

libuv/libuv#158 libuv/libuv#219

The change is currently pending review.

piranna commented 9 years ago

I've left as task for the reader to follow the rabbit hole... ;-)