Find local IP of a local server via JavaScript client - javascript

I have a Raspberry Pi and a computer, both connected to the same local network (both are connected to the same router, it's it's not the Pi who is acting as the router).How can I obtain the local IP address of the Raspberry Pi from a JavaScript script running in the computer (obs: by "client" I mean a JavaScript script running in the browser, not a node.js script)? I've thought of two approaches:
First one: To search for all local IPs, which would require the JavaScript client to know both his local IP and the subnet mask of the network, and would essentially try to get (via HTTP or whatever) some response from a specific port on the supposed Raspberry Pi IP address. However, I don't know how reliable that would be in terms of it taking too long to search the network and also of being able to obtain the local IP and subnet mask from the JavaScript client (from what I've read, the local IP is technically obtainable using a fake WebRTC request, even though it looks extremely unreliable; not so sure about the subnet)
Second one: To host a thin third-party server (on some other network) and make the Raspberry Pi server to send its local IP address to the server. When prompted by a request from the client, such third-party server would gracefully tell the Raspberry Pi IP address based on the public IP of the request (multiple requests could be handled from the third-party server, for various local networks).
I don't see why the second approach would not be viable. Is the first approach viable, however? And is there an easier way to solve the problem? Thank you.

Related

Find the private ip of an express server

I have a node express server running on Machine 1 as (0.0.0.0) and some client applications running on Machine 2, 3, and so on...
All machines are connected to the same Wi-Fi
How can I get the private IP of Machine 1 (which is running the express server), so that I can directly start calling the server APIs from client applications?
Note : I am using electron js in both server and client
There are a couple possibilities.
You can assign a local IP address to your server that does not change and thus is known. For example, on my LAN, I configure the auto-IP assignment to avoid 192.168.1.200 - 192.168.1.255 and thus I can manually assign those IP addresses to devices for which I want to have a constant and known IP address. Then, you can just refer to the "known" local IP address from your clients as in http://192.168.1.201/somePath.
You can configure local DNS (probably in your gateway router) so you can access your private server from your private LAN using a DNS name and combine this with option 1 so the IP address of your server won't change. You will need a router with this capability.
You can use a resource discovery service such as Simple Service Discovery Protocol (built into Windows) or BonJour (built into MacOS, available for Windows) if your client has the capability to use these. Your server will advertise its services in the resource discovery system and the clients can query the system to find the server.
The short answer is that you can't. HTTP servers don't broadcast their addresses.
You need to run some other kind of service (on the same machine as the HTTP server) such as zeroconf to provide discovery.
Then you need the clients to use it to find the server. You're probably out of luck if your clients are written in browser-side JS and you'll need to go to another level of complexity. I think DNS-SD is the way forward there.

How to discover a DHCP ip of an arduino in local network with javascript

I'm using an arduino UNO and an Ethernet Shield to create a web server to response HTTP requests.
The requests are sent by ajax XMLHttpRequest.
It's working fine with static ip address.
But a want the arduindo to get a DHCP ip, so I can use it in any local network (with DHCP).
I want to discover the ip of the arduino connected on the local network.
So I can use it as url to send HTTP requests.
Is it possible to do that in javascript?
OK, thanks for answering my questions above. That helped layout the network structure and the problem you're trying to solve.
Summary of the problem
Two computers: 1 web server whose address is dynamic (DHCP) and 1 web client running AJAX and HTML. How can browser find DHCP server?
Options
This is a classic problem solved many different ways throughout the history of computer networks. I've suggested some options below.
Scan for the server via TCP.
Scan for the server via UDP (requires special browser library).
Run a DNS server.
Have Arduino signal its IP.
Modify your router.
Don't run DHCP - use a static IP.
tl;dr - Use Option 6 if you don't control your router, Option 5 if you do.
Option: Scan for the server
I'm assuming you know your browser machine's IP address (for example, 192.168.1.17). In this case, run through all of the address from 192.168.1.0 through 192.168.1.254 (not .255 and skip you browser machine's IP) testing for a connection to port 80. This will find every web server on your subnet, so be aware you will need a way to recognize your arduino responded to the web request in case some other web server is also listening on the network. It will also take some time to set up, test and wait for timeouts on most (252) of the addresses which don't have web servers. You will eventually find it.
I'm not a fan of this one, but it gets the job done. Warning: if you don't "own" the network, someone may be angry with you for scanning their machines. A company, school or other institution may have policies about not scanning networks.
Option: UDP from the browser
This one is great, but requires a browser plug-in and some fancy coding. UDP allows one to broadcast a message to your subnet (try ping 255.255.255.255 at a command line and watch the machines echo back their IPs). If the arduino is set to listen for UDP packets on a particular port, it can echo back to the sender of the UDP packet and let that user know it's present. This is how DNS, DHCP, ping and Apple's Bonjour work. Many IP based systems advertise services by responding to UDP requests. Clients need not know the address of the servers on the subnet, they discover them through broadcast messages on well-known UDP ports.
Unfortunately, this requires a browser modification because Javascript does not support UDP for security reasons. I understand this and agree with the security restriction. However, it has cut out a really nice feature of dynamic service discovery. If you're on Apple on the browser, you might be able to find a Bonjour emulator you can run on the Arduino and it might work ("arduino.local" might attach). This might be possible with Windows service discovery, too, if you're using a Windows client for your browser. I don't know what's available in Linux for service discovery.
I don't like any of these modifications for you. Browser, Arduino (Apple, Windows or Linux), just because it adds more moving parts and you're counting on the browser to "know" how to find the service.
Option: Run a DNS server
This isn't as bad as it sounds, but I'm not sure the Arduino could handle it. Find a very small DNS server written for the Arduino and have it respond to DNS requests. On the browser, look for a well-known machine name (e.g. "my-arduino.lan"). This essentially finesses the UDP problem above by making the Arduino the UDP server (handles DNS requests) and the browser already has name resolution s/w (like every machine on the planet).
I didn't search for Arduino DNS code, it might be too large for the Arduino and writing it may be a real PITA (pain in the butt).
Option: Arduino signals IP
In this model, you can attach a LCD to the arduino and have it present its IP address on the display. Alternatively, the arduino can send a message (via TCP) to a well known server on the network (internet or otherwise) reporting its IP address there. Your browser can query that server, pick up the IP address and then contact the Arduino directly. This introduces a 3rd machine and acts like your own hacked form of DDNS (look it up, if you're not familiar with it).
Option: Modify the router
If you own the router, you can modify the router to assign a specific IP address to the Arduino, even with DHCP. This is your best bet. Here, you control the network, can allow the Arduino to come up in DHCP while still fixing its IP address. You'll have to go through your router API (web or CLI) and figure out how to do it, it's a bit hard directing you as there are thousands of types of commercial and SOHO routers.
If you don't control the router...
Option: Use Static IP
This option is really your best. Give up on DHCP and just set the static IP of the arduino. Just make sure the IP address you pick doesn't conflict with any other servers on the subnet. That shouldn't be difficult.
I hope this helps.
The 2 best options I think:
1) When arduino starts, gets an IP address from DHCP, arduino should make a connection to a well know service provided by you. Also, each device should have an ID, defined by you during manufacturing, like mac address or part of mac address.
So, you can print on the box something like: 5c4e6f.my-well-know-host.com
Than, as I was suggesting, each time arduino starts, it tries to connect to that service passing parameters like:
POST www.my-well-know-host.com
ID: 5c4e6f
IP: 192.168.1.55
than, at that service, you update a DNS table to reflect this relation:
5c4e6f.my-well-know-host.com -> resolves to 192.168.1.55
obviously, from anywhere in the world the host 5c4e6f.my-well-know-host.com will resolve to 192.168.1.55, but you will only access it from you local network.
Tip: this is some kind of DDNS, but with network discovery purposes.
Tip2: there is an linux dns service called MyDNS, where the hosts are simply records inside a MySQL table, easy to maintain.
2) Network discovery
I don't know if arduino is capable to do it, but, the idea is to make arduino listen on a specific UDP port, like 4444, on any address.
So, you can build a windows app, and Android APP (I already made one android discovery for another purpose, not arduino), or, the best solution that I still researching on, is to make a custom page with some javascript code, that "looks" for devices listening on that specific port.
Works like that:
Device gets IP from DHCP
device starts a thread listening for broadcast packets on port 4444
a discovery app listen on another port, like 4445.
the discovery app announces itself using a broadcast packet to 4444 port (255.255.255.255:4444)
each device listening, reports back with its identification and IP to app port 4445.
This is a code to find the server ip:
<script type="text/javascript">
var ip = "<?php echo $_SERVER['SERVER_ADDR']; ?>";
alert(ip);
</script>
If you are using Johnny Five framework, then you can find APIs in that framework

Is there a way to send a TCP request to the client through the browser?

I am working on a web application. I want to know certain parameters of the client's machine. I have been able to find out most of the parameters but I am struck in the following parameters.
1) TCP Timestamp
2) TCP/IP FingerPrint
So, my question is, Is there a way to send TCP request to the client through my web application(assuming I know the client's IP address). Or is there any way around to find out these parameters on the client's machine. Any hint on how to get started will be appreciated.
So, my question is, Is there a way to send TCP request to the client through my web application(assuming I know the client's IP address). Or is there any way around to find out these parameters on the client's machine. Any hint on how to get started will be appreciated.
If you can use sockets (not websockets) from your web application than you could try to establish a TCP connection to the client. But this will probably not work in most cases, because:
The client will not listen for TCP connections from outside, so you would get at most a RST packet.
Clients are mostly behind some NAT device today, like a router at home or inside a mobile network. Therefore the source IP you see from the client connection to your server is in most cases not the IP of the client itself, but of the NAT router. Since the client has no public IP address it can not be reached directly.
1) TCP Timestamp
2) TCP/IP FingerPrint
These are usually not parameter you find out by doing a simple TCP request, but you need to work with raw sockets. Also, part of these information can be derived from the established connection, but you must be able to track the connection on the raw level (like with tcpdump).

Local network P2P file transfer

One of my University assignments is to develop a P2P file sharing web application to transfer files between machines on the same local network. I'm not looking for a handout on how to do this, I can figure it out once I get the high level design down, I just need to know if this is sane.
I'm planning on using the PeerJS library. From what I can tell each client gets a unique ID and these IDs are used to connect clients to each other. So somehow I need to coordinate IDs between all the clients on the same local network.
The way I was planning on doing this is to have a NodeJS server running with Socket.IO. When the client loads the web application, they send a websocket request to the Node server. The node server then records the external IP address of the client. When another client connects and makes a request with the same external IP address as another client, those two clients are given each other's IDs so they can connect to each other.
There are a few potential problems with this:
I'm assuming people with the same external IP address are on the same local network. Would this be wrong in any situations?
I don't know how the file transfer between clients will happen. Ideally it should be isolated to the local network. For example if I'm transferring a file between two computers it will go: computer 1 -> router/switch -> computer 2, not something like computer 1 -> router/switch -> local exchange -> ISP switch -> local exchange -> router/switch -> computer 2. Basically the transfer shouldn't leave the local network onto the Internet.
Thoughts?

Javascript socket connection

A server that sends info (in this case temperature data, every second) through a socket connection which can be listened to.
The goal being to display temperature and dynamically update the value on a webpage, with javascript.
The server cannot be modified.
JavaScript can not open arbitrary TCP connections, as that would allow for all kinds of mayhem when combined with services who authenticate based on IP address, or not at all (and are only protected by firewalls). This includes Windows or NFS file shares, your average printer, your average LAN game, your average home router's web interface and lots of enterprise software.
You you cannot really prevent the browser from visiting a malicious site (since that includes visiting a trusted site with malicious ads). If these sites could effect arbitrary TCP connections, they could for example try out every IP address in the RFC 1918 private address ranges, or every IP address in the address range of the organization the client is coming from, and determine what devices you own. That alone would constitute a serious privacy breach, but imagine a malware site finding a printer and then printing out spam in your office once you visit it by accident.
What you can do is use a WebSocket server to translate native TCP to WebSockets. Most Websocket implementations will have such a server as a demonstration app, but you can also use a standalone proxy.
What you need to do is make the connection with PHP, or something else server side, and return the result via AJAX to your JavaScript.

Categories