Finding hostname of connected devices

Hello,

I have searched the forum and found issues similar to what I'm about to describe but not quite what I am after. There are a few paths I can think of to solve my problem but I'm not sure how to pursue any of them.

My IT department does not allow static IP's or any server/network changes. I am using three raspberry pi's for my project. Because there is the potential for each Pi's IP address to change I can't reliably use them. Hostname seems to be the way to go.

I am wanting to run Node-Red on the "main" Pi and then have the other two Pi's connect to the dashboard. I prefer not to have any Node-Red code running on the two remote Pi's. I have no problem connecting them to the dashboard. But I want to be able to reliably know if they are connected or disconnected from the dashboard. It is important that I have reliable status.

I have been able to use the ui_control node to detect "connect" and "lost" events and I can retrieve the IP address of each event using msg.socketip. However since the IP address could change, I would no longer know which IP address is which Pi. Other desktop or laptop devices might view the dashboard as well but I don't care about their status.

Is there a way I can search by hostname and see what the current IP address is assigned to that hostname? Then I could compare the list of connected IP addresses to the IP addresses associated with the appropriate hostnames?

Am I on the right track?

There is a little flow at [Scan LAN/Subnet for devices (flow) - Node-RED]

It uses nmap whch is not installed by default on RPiOS.

On my Pi the command used gives this:

sudo nmap -sn 192.168.1.0/24 | awk '/Nmap scan report for/{printf $5;}/MAC Address:/{print " "substr($0, index($0,$3)) }'
192.168.1.1 E8:48:B8:GG:GG:GG (Unknown)
192.168.1.11 DC:A6:32:GG:GG:G (Raspberry Pi Trading)
192.168.1.24 B8:27:EB:GG:GG:GG (Raspberry Pi Foundation)
192.168.1.41 24:62:AB:GG:GG:GG (Espressif)
192.168.1.51 4E:3F:7E:GG:GG:GG (Unknown)
192.168.1.61 D8:49:2F:GG:GG:GG (Canon)
(etc)

If you know the various Pies MAC address(es) you can find their IP and connected status.
Mind you, the admins might dislike you using this on their network.

Another possibility would be hostname and IP address sent to a cloud based MQTT broker as a "heartbeat".

I appreciate the ideas. I'm not sure how the admins will feel about Nmap either. Also I'm not familiar with Nmap but if it returns all devices on the network there will be 1000's.

Although if there's another way to find the MAC address associated with an IP address I hadn't thought of that.

I had thought of option 2 but I'm trying to avoid as much setup and coding on the two remote pi's as I can. So ideally I would just have them point to the dashboard on boot and that is it.

Maybe I am looking at it the wrong way but I don't know of another way to see a connect/disconnect to the dashboard other than ui_control.

I found the node-red-contrib-arp node interesting at first. But it appears to do something similar to Nmap. I don't think scanning the network for connected devices is going to be an option as I've read the delay can be pretty long if there are a bunch of devices (which there are hundreds if not thousands of devices sharing the network in the facility).

Hopefully there is a way to key off the hostname or MAC address without scanning the entire network. Once again maybe I'm way off track though.

I suspect it would not be difficult to add the MAC address to the ui_control connected message. It would need someone with the appropriate knowledge to implement it however.

This would have been a good option but of course, it suffers from the same problem that the MQTT broker's device might change IP.

The best option would be to get your IT department to register the devices as servers and either fix their addresses using DHCP allocations or give them proper server names so that it doesn't matter what their IP addresses are.

Every other option will need a server with a fixed name or address somewhere and if you don't have that, you are going to be stuck.

Would not MAC address in the ui_control connected message solve the problem? Or is there a technical problem implementing that?

How would the client connect in the first place if the Node-RED server had changed IP address?

If we could assume that the Node-RED server has a fixed IP or a DNS name, then the best option overall would be for Dashboard to give each client a UUID upon connection. That UUID could then be retained and used instead of any other identifier (noting that the client socketid which is the other identifier you can work with changes if the user reloads the page or it temporarily disconnects for some reason).

This is one of many conundrums I'm looking at with the uibuilder security model. Everyone thinks that you can just create a JWT and walk away. Very much not true of course.

To make matters more interesting, if you don't want to rely on cookies, you have to note that custom HTTP headers only work for HTTP requests and not for websocket comms. The handshake for websockets happens over HTTP but then it "upgrades" to websockets and you loose your headers. So JWT's don't work well with websockets unless you put the JWT into every message. Not a problem if you don't need to deal with IP address changes and/or session expiry but certainly a problem otherwise.

So I think that the best approach would be for Node-RED to create a unique identifier and maintain a list of connections in a table. Of course, because of Node-RED's flexibility, you can almost certainly add this without changing Dashboard by, as you suggest, using the connect node to send an identifier that you then track. You would then need to use a ui_template though in order to add the identifier to any outbound message (can you even do that with Dashboard? Not sure) which is similar to what I'll be doing with uibuilder assuming I can ever get all the pieces of the jigsaw to line up and not trip over each other!

Of course, if the Node-RED server ever changes IP, it is game over. :skull_and_crossbones:

I appreciate the discussion we are having and I might have found a solution. I installed the node-red-contrib-arp module and played around with it a little bit yesterday. Being able to filter by MAC address and returning an object with the associated IP address appears to be exactly what I am after. Although this is working it has led me to a couple of questions.

I found it strange that only the two Pi's I currently have connected show up when leaving the arp node blank. None of the other devices on the network show up. I was anticipating that all devices connected to my LAN would show up. Will this be a problem when I take the Pi's to their respective deployment zones? (They are located in different buildings, but have access to the same network)

Also another weird issue I encountered is when running the arp node from my PC (Windows 10). When attempting to run the node I receive the error: "Error: Command failed: arp -n". However, if I run various arp commands from the cmd line (arp -a, arp -n, etc) they all work successfully. Is there another package or something I need to install to make it work within node-red on Windows?

arp only works on the local subnet, I think. However, once you know the IP you can use arping to get the Mac from the IP. That does work across subnets.

That's why I suggested a cloud based broker!

Hi @jgreenmt,

Apart from the MQTT suggestions, there are two other ways to do this I can think of.

1. Hostname

Make sure it's unique for each Pi. Change it using hostname <newhostnamehere> and also remember to update your hosts file.

For example, if you had rpi1, rpi2, & rpi3, and all three pi's are on the same network, just using ssh pi@rpi2 from rpi1 should work fine.

Sometimes that doesn't work so option 2 may be useful (mDNS).

2. mDNS

mDNS. It's easy to get running on a Pi using Avahi. There is some info on this page (search for Avahi). There are probably many other places to look this up.

What mDNS does is it broadcasts a DNS address on a local network without needing to use a DNS server. By default it uses the .local suffix. So ifyou used the hostnames above, to connect you'd use ssh pi@rpi1.local. Remember to allow mDNS in your firewall settings.

Monitoring the connections

From your main machine running Node-Red, just have node-red ping it at whatever frequency would work for you.

Or you could use the netstat command to look for active connections.
netstat | grep 1880 (this would show all connections to port 1880, the default node-red port on the machine the command is being run on).

Example:

user@lazza:~$ netstat | grep 1880
tcp        0      0 lazza.lan:1880          2012imac.lan:59790      TIME_WAIT  
tcp        0      0 lazza.lan:1880          2012imac.lan:59791      TIME_WAIT  
tcp        0      0 lazza.lan:1880          2012imac.lan:59792      ESTABLISHED

I think that the original question indicated that this is a controlled network. So:

Will only help if the network is set up to recognise it and let you use it. That uses an internal DNS or similar so that you can use IP names such as HOSTNAME.local. In that case no need to mess with IP addresses at all.

However, you would need to agree the hostname with the IT department.

Hmm, well that is likely to be even less welcome on a corporate network than running network scans :slight_smile:

I have been trying to make use of arping as Colin suggested. I am testing with another machine I know is on a different subnet. I am using the command sudo arping -c 1 xx.xx.xx.xx but the output I received stated that 1 packet was transmitted but 0 packets were received. However I can ping this IP address and get responses properly so I know the device is connected to the network.

I read that I might need to use the -p modifier but I have tried in two locations: sudo arping -p -c 1 xx.xx.xx.xx and sudo arping -c 1 xx.xx.xx.xx -p and neither changes the output.

This is the complete output response I get from the cmd prompt with the IP address x'd out:
arping: lookup dev: No matching interface found using getifaddrs().
arping: Unable to automatically find interface to use. Is it on the local LAN?
arping: Use -i to manually specify interface. Guessing interface eth0.
ARPING xx.xx.xx.xxx
Timeout

Any suggestions on how I can get a response from the device?

I would still like an answer to my latest post about using arping across different subnets, but I should probably open the topic in a new thread.

Using netstat appears to be a very simple solution for what I'm wanting to achieve in this specific scenario.

Thank you to all who contributed.

Sorry, it appears that I was mistaken, arping does not work across subnets.