How to scan network for devices, using C Obj C or Swift - objective-c

I have a server running on a Raspberry Pi and a client running on my Mac and iPhone (soon Apple Watch). I would like to connect to my server automatically without finding the Raspberry pi's Ip-address.
Is there a way to lookup all the devices on the network, and select by Mac-address, name or something else? I know that the first 3 bytes of the mac-address is the same for all Pies. (B8:27:EB) Maby i can use that information.
I have been looking for a solution for this issue a while but i can't seem to find one.

Zeroconf (aka Bonjour)
IMO, the best way to do this is to have your Raspberry Pi advertise itself on the network using Zeroconf (aka. Bonjour).
On the Raspberry Pi, install avahi-daemon and configure it to advertise whichever service you'd like to connect to connect to, for example, if you're connecting via SSH, you'll need to do something like this.
In Cocoa, you can use NSNetServiceBrowser to find the advertised service.
Possible MAC Address solution
Alternatively, if Avahi-daemon is not an option, you may be able to use the MAC address. I will not go into the specifics in Objective-C, just a high-level overview using the command-line.
In terminal, type ping 255.255.255.255. You will get back ping packets from every device on the local network. For each IP address, send an individual ping e.g. ping -c 1 192.168.x.x. Then, type arp -a. You will see the MAC address for each IP on the local network. From here, you can perhaps use your MAC address filter to find Raspberry Pis.
Why does this work? Well, the first command ping 255.255.255.255 sends a ping in an IP packet to the 'broadcast' address, which means all machines on the local network respond. When you ping the individual IP addresses, the low-level networking stack uses ARP to find the MAC address of the IP to directly send a ping to it. In doing so, the ARP tables on the local machine are updated with the cached values.
Maybe you can use this method in your app to discover local Raspberry Pis.

Related

Proper way to connect to IOT devices (UDP or ICMP)

What is the proper way to connect an app to a device? At the moment, I have a raspberry pi 3 that controls something about electricity and an iPhone app I created. Every time the app goes to foreground, it sends a UDP broadcast message, when the app receives a response from the raspberry pi, it uses that IP address (in the IP header) to consume the web services I created in the hub. This UDP process is done all the time you run the app. Is this what IOT devices usually do? I assume the raspberry pi IP will change sooner or later.
A colleague of mine told me another way: After the first time I get the IP address, instead of using UDP broadcast messages every time the app runs, use ICMP to ping the previously saved IP address to see if it is responding. In that case, I use the web services with that IP address, otherwise, use the UPD broadcast message again.
I don't see the point of that. Basically because the system is not faster using ICMP. (a UDP request is more or less as fast as an ICMP request). Moreover, maybe, another device started using that IP address now (like a smart TV or a smart plug) and for that reason, it is not going to reply to the network requests sent by the app. In that case, the app cannot recover, because it thinks it is already connected to the proper device. As far as I understand, ICMP is a protocol use for diagnosis, not for devices discovery.
What do you think? What's the process used by devices like Alexa, Philips Hue, Smart plugs... to solve the problem of discovering the devices by their apps?
It seems Philips HUE is using SSDP, which under the hood uses a UDP broadcast message. Is it used every time you run the app to discover the IP address? (I am going to check this later with wireshark)
Thanks for suggestions.
You can enable the hostname of your Raspberry Pi to be accessible on your local network through:
http://raspberrypi.local
To enable it, you need to install Bonjour support on your Raspberry Pi by installing the Avahi mDNS daemon (implements Apple's Zeroconf architecture):
$ sudo apt-get install avahi-daemon
Update boot startup:
$ sudo insserv avahi-daemon
Restart to apply the new configuration:
$ sudo /etc/init.d/avahi-daemon restart

Remote connection to embedded device in field

I would like to ask about the way how to establish remote connection to Linux based embedded device in the field.
I have a small linux board I want to place in remote location. It has an internet access through ethernet. Than I have a Linux server with public IP to be able to tunnel connection.
And finally, I want to connect from my PC to this device.
I don't feel yet competent enough to code my own tcp sockets etc. to reroute the connection :) So what would be the easiest way to do that only with available linux tools? And BusyBox toolset on endpoints.
Thank's a lot!
I think that using OpenVPN would be a easy way to tunnel to the device. You can cross compile it and set it up as a client on the embedded device. Then you install it on your Linux box and set it up as a server.
Finally you install it on your work PC and set up as a client there.
It gives you a virtual network where all clients can talk to each other like they would be on a local network.

Raspberry pi on remote network (all done works are mentioned in details)

Firstly,here, I will mention all what I did to make raspberry pi as a web server or as a data cloud. But all the issues which were applied did not work. There are some problems in somewhere , but I dont know where, what , how.. ?
So let me start.
Firstly,I booted my raspberry pi with Raspian OS. It works in a best manner for sure.Then, I installed ntfs-3g to make it possible to read my hard drives by raspberry pi.
When I connected my hard drive (500 GB), raspberry pi went crazy,it freezed and so on.
I have two hypotheses. One of them , maybe hard drive could be so huge for raspberry pi to read and it could take lots of time to read.
But someone could do with 1TB hard drive. So this one is dead!
Another hypothesis is that hard drive is formatted with NTFS. Maybe it could be problem.
At first, I booted raspberry pi from a usb storage and when I connected that hard drive, raspberry tried to boot itself from hard drive, not from usb.That's why this is one another hypothesis. I havent disproved this yet. But i will and let you know.
Although I could not connect my hard drive to raspberry pi, I gave a break to that issue and I tried to create a connection from remote network to my raspberry pi.
I made raspberry's IP as a static. I could connect it from ssh and file zilla(ftp) LOCALLY. I disabled firewall of my router and observed my router's external IP. It has not changed for many days although I dont have a static external IP. Then, I arranged my port forwarding like these
"router_external_IP":8080 destination(raspberry's internal IP) is 22 (for SSH)
"router_external_IP":9000 destination(raspberry's internal IP) is 80 (for HTML)
"router_external_IP":8500 destination(raspberry's internal IP) is 3306(for mySql)
When SSH server and Mysql server ran on the raspberry pi, I tried to connect to raspberry pi
by SSH with "router_external_IP":8080 (from putty)
by browser with "router_external_IP":9000
by browser with "router_external_IP":8500
NO ONE WORKED :( ! [By the way, I installed web servers on it, but i did not mention]
Someone can say that "Are you sure about ports are open ?".
Yes I am sure I checked it out. But I am not sure on my router are forwarding these ports to raspberry pi or not . Also, I can not debug it.
Actually, I have 2 hypotheses on that also.
First one is that maybe router does not forward these ports to raspberry pi.
Second one is that maybe I am doing something wrong and that is why although router forwards all given ports to raspberry, raspberry can not respond.
I can not disprove these since I dont know how to debug.
I do not know what to do. I just got lost. Please help me on these issue.
An easy way to check if your router is forwarding your ports is to check them at: http://canyouseeme.org . If, as you say, all your ports are open on your internal network, if "canyouseeme" can't see your services then you know you need to tweak your router settings.

How to detect an Arduino Yún / Yún shield IP address on a LAN

I'm writing code on a server to interact with an Arduino Yún shield via SSH. Is there a way for the server to detect the Yún shield LAN IP address automatically just like the IDE?
I ran into this and found out that the Yún runs a Bonjour compatible daemon called Avahi which sets a domain of arduino.local in your local network which makes the IDE aware of the board existence. I know because I have a Yún shield (not Yún) which by default gets assigned a different Bonjour name so the IDE can't recognize it.
So, if you need to access the Yún by name locally check the Avahi daemon configuration to see what name is used. If you need to access it from outside it's still possible by using a service like noip and opening the port on your router.
Please mark the answer as correct if this answers your question.
It is not possible as your device may get an IP address from the ISP dynamically. Your device has to connect to your server and tell its IP address.
You can try something like, TCP/IP.

How to detect all devices in a LAN?

I want to detect all devices in a LAN which have IP: 10.x.x.x Mask: 255.0.0.0.
I first wrote a synchronous ping program to ping IPs one by one, but it's tooooo slow.
Therefore I improved it by using asynchronous ping, then it's much faster.
Now I can use it to detect 10.x.0~255.0~255 in an acceptable time.
But it still use tooooooooooooo long time to detect all the IPs 10.0~255.0~255.0~255.
Is there any method/protocol that can just broadcast one message and let all devices in a LAN to respond, so I can detect all the devices?
(either Ethernet broadcast or UDP/IP broadcast or any other broadcast.)
(I've researched ARP & ICMP but haven't find suitable methods.)
Or any other method even don't need broadcast?
I just need to detect all the devices, any method is OK.
Not sure if it's what you are looking for but you can go in command prompt and run the command:
arp -a
I recommend "Angry IP Scanner" http://angryip.org/
It is fast, detects all devices in a given ip/netmask.
Angry IP scanner is a very fast IP address and port scanner.
From site:
It can scan IP addresses in any range as well as any their ports. It
is cross-platform and lightweight. Not requiring any installations, it
can be freely copied and used anywhere.
Angry IP scanner simply pings each IP address to check if it’s alive,
then optionally it is resolving its hostname, determines the MAC
address, scans ports, etc. The amount of gathered data about each host
can be extended with plugins.
It also has additional features, like NetBIOS information (computer
name, workgroup name, and currently logged in Windows user), favorite
IP address ranges, web server detection, customizable openers, etc.