espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.53k stars 7.26k forks source link

arp and nslookup equivalent commands in esp-idf (IDFGH-6532) #8183

Open twlawrenceko opened 2 years ago

twlawrenceko commented 2 years ago

Hello,

I have looked through the provided examples but have not seen one that is equivalent to the command arp -a and nslookup command to print out all devices connected to the same Wi-Fi as the ESP device. Is there any way to retrieve local devices IP address, MAC address, and hostname of each device?

Thank you.

mhdong commented 2 years ago

hi @twlawrenceko You can use the following two APIs to get MAC address and IP.

esp_wifi.h /**

tcpip_adapter.h /**

negativekelvin commented 2 years ago

@mhdong I think he wants to do subnet scan of the router when esp is station so those apis won't help

twlawrenceko commented 2 years ago

Hello @mhdong , Yes, @negativekelvin is right, I would like to do a subnet scan of the router when esp is station and to check whether a phone device is in the subnet or not.

xueyunfei998 commented 2 years ago

esp_arp.txt lwip_arp.txt

xueyunfei998 commented 2 years ago

hi @twlawrenceko

I added an interface to query arp table records.

nslookup is used to query the records of DNS and whether the domain name resolution is normal.

getaddrinfo this interface can be used in idf, this interface queries the ip address corresponding to the domain name.

negativekelvin commented 2 years ago

@xueyunfei998 ok but how would you suggest populating that table in the most efficient way? How would you quickly scan a whole /24 subnet?

xueyunfei998 commented 2 years ago

@negativekelvin

His demand should be to query the records of local arp table. There is also a domain name query to see if the network is unobstructed. Right? @twlawrenceko

twlawrenceko commented 2 years ago

@xueyunfei998 What we would like to achieve is the detect whether a device is now connected or not. For example, if the computer wakes up and connects to the same Wi-Fi as ESP, then the ESP can detect that. With that idea, I think the local arp table can be first scanned and then how to trigger ESP to detect whether a device becomes online or not is the question we would like to ask. Of course we can continuous using arp scan, but as @negativekelvin mentioned, it may take too long.

xueyunfei998 commented 2 years ago

hi @twlawrenceko

The meaning expressed in all your statements above:

If esp32 is a sta mode connection router, then you think esp32 can scan all the devices in the same network segment under this router.

Is that what you mean?

twlawrenceko commented 2 years ago

@xueyunfei998 I don’t mean by 100%. I mean by if a device was originally detected (via arp or such), then it can detect whether it is currently online or not.

Or the other way, if the device IP is provided, then the ESP can detect whether it’s online now or not by either arp scan to see if it’s in table or ping.

xueyunfei998 commented 2 years ago

@twlawrenceko

ok,Now that I know what you need.

Whether the mode of esp32 is ap or sta, esp32 wants to know which devices are in a network segment and whether these devices are online.

First, if you want to know whether the device is online, need the device to push online messages in real time.

If this is the case, it is better to make a heartbeat packet real-time broadcast device online in the application layer, instead of scanning arp table.

The application layer heartbeat packet, preferably uses udp communication to broadcast the information of the device.

It is difficult to know whether the device is online from wifi level or lwip level, because although arp table knows the information of other nodes, it is not effective, and arp table will not keep the information if it does not communicate with other nodes.

Therefore, it is recommended to redefine a private protocol in the application layer to complete this function.

negativekelvin commented 2 years ago

@xueyunfei998 sure mdns or custom protocol could work but user does not always control the target devices. So you are saying there is no way to send and receive arp packets from application layer?

xueyunfei998 commented 2 years ago

@negativekelvin

Because arp is an ip layer protocol, the application layer is not easy to operate through socket.

However, esp32 has a function Garp, which is that esp32 broadcasts address information through ARP every 60 seconds (this time can be configured)

You can reduce this time, let esp32 devices frequently broadcast their address information, and then check arp table to complete this function.

negativekelvin commented 2 years ago

@xueyunfei998 as mentioned before other devices may not be esp32 based or configurable by user. Arp table size can be limiting factor too. What about installing hook at netif layer to inject and capture arp packets?

xueyunfei998 commented 2 years ago

hi @negativekelvin

Check whether the device is online through arp function, that is, receive the arp requset packet of the other device.

If other devices are not developed based on esp32, they may not have free arp function. If the device does not send data, it may not send arp requset.

You mentioned above to add an arp hook, which is a new function. I can add a function when receiving arp packets, and return the ip address and mac address of the other device. You can judge whether the other device is online by the returned address. Do you think it's ok to do so?

negativekelvin commented 2 years ago

Need to be able to send arp requests from esp32 ("who has 192.168.0.2") and receive the arp replies with Mac address.

xueyunfei998 commented 2 years ago

hi @negativekelvin Need to be able to send arp requests from esp32 ("who has 192.168.0.2"):

receive the arp replies with Mac address:

negativekelvin commented 2 years ago

@xueyunfei998 yes callback is good. Can you add example or unit test code for sending arp request and receiving response from callback?

featherfly commented 1 year ago

@xueyunfei998 the feature arp_request is ok now ?