This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Is there any way that I can get DHCP table?
#1
Is there any way that I can get DHCP table? I need to get the IP address (and name or MAC if possible) of all device on the network. Thank you
Reply
#2
This depends on what kind of router you have and how easy it is to get information from it. Mikrotik is fully supported, Unify should also be possible via HTTP API. If you want to do presence detection this way you need ARP table instead of DHCP.
Reply
#3
(31.12.2020, 12:14)admin Wrote: This depends on what kind of router you have and how easy it is to get information from it. Mikrotik is fully supported, Unify should also be possible via HTTP API. If you want to do presence detection this way you need ARP table instead of DHCP.

Can you tell me how to do? I use os.execute('arp -a') or get info from proc/net/arp but they show nothing. 

I want to find a device that use DHCP (because it doesnt has option to use static IP) and want to find it whenever it's local IP change. Currently I use this code to ping to every IP from 1 to 255 and find it but it's way too slow. So it's best if I can find IP of all device on the network, and look for it by it's name or MAC but I dont know how to do

Code:
for i = 1, 255 do
  ip = '192.168.1.' .. i
  res = os.execute('ping -c 2 -W 1 ' .. ip)
  if res == 0 then
    url='http://'..ip..'/httpapi.asp?command=getPlayerStatus'
    require('socket.http')
    res, err = socket.http.request(url)
    if res ~= nil then
      t1, t2 = string.find(res, 'Artist')
      if t1 ~= nil then
          --my code
      break
   end
  end
 end
Reply
#4
This has to be done on your router. See if you can enable a static DHCP entry for a certain MAC.
Reply
#5
(31.12.2020, 13:09)admin Wrote: This has to be done on your router. See if you can enable a static DHCP entry for a certain MAC.

How can some software like Fing on mobile or Angry IP Scanner can scan all IP in the network so fast, They send some UDP packet and get response I think?. I use packet capture and see that they send request to port 137 (NetBios) of all the IP from .1 to .255 and see the response to see if the IP is available. I want to do something like that, is it possible

(31.12.2020, 13:09)admin Wrote: This has to be done on your router. See if you can enable a static DHCP entry for a certain MAC.

And the device will be move from house to house, it means that I should write a code to detect the device so I don't need to setup every router that it will be install.


Currently I use this code to ping to every IP from 1 to 255 and find it but it's way too slow. So it's best if I can find IP of all device on the network, and look for it by it's name or MAC but I dont know how to do
1
Code:
for i = 1, 255 do
  ip = '192.168.1.' .. i
  res = os.execute('ping -c 2 -W 1 ' .. ip)
  if res == 0 then
    url='http://'..ip..'/httpapi.asp?command=getPlayerStatus'
    require('socket.http')
    res, err = socket.http.request(url)
    if res ~= nil then
      t1, t2 = string.find(res, 'Artist')
      if t1 ~= nil then
          --my code
      break
   end
  end
end
Reply
#6
You should save the device IP in storage and periodically run the scan via a scheduled scripts to check for IP changes. You should also set a lower value for socket.http.TIMEOUT because default is 60 seconds to speed up the script. Check if your device has a non-standard TCP port open so the scan more consistent, because many network devices can have port 80 open.

Here's a script that can quickly check if any of local IPs have port 80 open:
Code:
require('socket')
prefix = '192.168.1.' -- ip address prefix
rangemin, rangemax = 2, 254 -- min/max of the scan range
port = 80 -- TCP port to check

sockets = {}
ips = {}

-- create sockets and connect
for i = rangemin, rangemax do
  ip = prefix .. i
  
  sock = socket.tcp()
  sock:settimeout(0)
  sock:connect(ip, port)

  sockets[ #sockets + 1 ] = sock
  ips[ sock ] = ip
end

-- get a list of sockets that can be written to, this means that the connection is established
_, res, err = socket.select(nil, sockets, 1)

res = res or {}

-- log IPs of all sockets that accepted the connection
for _, sock in ipairs(sockets) do
  if res[ sock ] then
    ip = ips[ sock ]
    log(ip)
  end

  sock:close()
end

-- clean-up in case running as a resident script
sockets = nil
ips = nil
Reply
#7
(04.01.2021, 07:57)admin Wrote: You should save the device IP in storage and periodically run the scan via a scheduled scripts to check for IP changes. You should also set a lower value for socket.http.TIMEOUT because default is 60 seconds to speed up the script. Check if your device has a non-standard TCP port open so the scan more consistent, because many network devices can have port 80 open.

Here's a script that can quickly check if any of local IPs have port 80 open:
Code:
require('socket')
prefix = '192.168.1.' -- ip address prefix
rangemin, rangemax = 2, 254 -- min/max of the scan range
port = 80 -- TCP port to check

sockets = {}
ips = {}

-- create sockets and connect
for i = rangemin, rangemax do
  ip = prefix .. i
 
  sock = socket.tcp()
  sock:settimeout(0)
  sock:connect(ip, port)

  sockets[ #sockets + 1 ] = sock
  ips[ sock ] = ip
end

-- get a list of sockets that can be written to, this means that the connection is established
_, res, err = socket.select(nil, sockets, 1)

res = res or {}

-- log IPs of all sockets that accepted the connection
for _, sock in ipairs(sockets) do
  if res[ sock ] then
    ip = ips[ sock ]
    log(ip)
  end

  sock:close()
end

-- clean-up in case running as a resident script
sockets = nil
ips = nil

Thank you. I will test it soon

It work like a charm
Reply
#8
(04.01.2021, 07:57)admin Wrote: You should save the device IP in storage and periodically run the scan via a scheduled scripts to check for IP changes. You should also set a lower value for socket.http.TIMEOUT because default is 60 seconds to speed up the script. Check if your device has a non-standard TCP port open so the scan more consistent, because many network devices can have port 80 open.

Here's a script that can quickly check if any of local IPs have port 80 open:
Code:
require('socket')
prefix = '192.168.1.' -- ip address prefix
rangemin, rangemax = 2, 254 -- min/max of the scan range
port = 80 -- TCP port to check

sockets = {}
ips = {}

-- create sockets and connect
for i = rangemin, rangemax do
  ip = prefix .. i
 
  sock = socket.tcp()
  sock:settimeout(0)
  sock:connect(ip, port)

  sockets[ #sockets + 1 ] = sock
  ips[ sock ] = ip
end

-- get a list of sockets that can be written to, this means that the connection is established
_, res, err = socket.select(nil, sockets, 1)

res = res or {}

-- log IPs of all sockets that accepted the connection
for _, sock in ipairs(sockets) do
  if res[ sock ] then
    ip = ips[ sock ]
    log(ip)
  end

  sock:close()
end

-- clean-up in case running as a resident script
sockets = nil
ips = nil

Is it possible to get Name and MAC adress with this script?
Reply
#9
You can get a list table with IP -> MAC mapping from the ARP table like this:
Code:
macs = {}
lines = io.readfile('/proc/net/arp'):split('\n')

-- skip first and last line
for i = 2, #lines - 1 do
  ip, _, _, mac = unpack(lines[ i ]:gsub('%s+', ' '):split(' '))
  macs[ ip ] = mac
end

log(macs)

Name is a part of DHCP and only the DHCP server / router has this information.
Reply
#10
Is there a way to rewrite this where you specify IP and get the Mac address in return?
Reply
#11
macs table already contains ip -> mac mapping:

Code:
ip = '192.168.0.2'
mac = macs[ ip ]
log(mac) -- will log the mac address for 192.168.0.2 if found
Reply
#12
Many thanks, works great!
Reply


Forum Jump: