Logic Machine Forum
Is there any way that I can get DHCP table? - Printable Version

+- Logic Machine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8)
+--- Thread: Is there any way that I can get DHCP table? (/showthread.php?tid=3085)



Is there any way that I can get DHCP table? - pouralise - 31.12.2020

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


RE: Is there any way that I can get DHCP table? - admin - 31.12.2020

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.


RE: Is there any way that I can get DHCP table? - pouralise - 31.12.2020

(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



RE: Is there any way that I can get DHCP table? - admin - 31.12.2020

This has to be done on your router. See if you can enable a static DHCP entry for a certain MAC.


RE: Is there any way that I can get DHCP table? - pouralise - 31.12.2020

(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



RE: Is there any way that I can get DHCP table? - admin - 04.01.2021

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



RE: Is there any way that I can get DHCP table? - pouralise - 05.01.2021

(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


RE: Is there any way that I can get DHCP table? - victor.back - 10.01.2021

(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?


RE: Is there any way that I can get DHCP table? - admin - 11.01.2021

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.


RE: Is there any way that I can get DHCP table? - FatMax - 11.01.2023

Is there a way to rewrite this where you specify IP and get the Mac address in return?


RE: Is there any way that I can get DHCP table? - admin - 11.01.2023

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



RE: Is there any way that I can get DHCP table? - FatMax - 11.01.2023

Many thanks, works great!