I just finished understanding what's UPNP (universal plugs and play).
Now supposing it's enabled in my router, how can I used UPNP to detect devices connected to the network and analyzing it (it's a fridge, printer etc?)
I'm looking to work with C/C++ and not sure where to start from.
UPnP is a collection of active and passive discovery protocols. Either hosts send advertising multicasts on their own, or they need to respond to search requests. Interested parties can then query the varies capabilities ("description") of a discovered service.
Hosts not directly supporting the required protocol cannot be discovered.
Related
I am a newbie to AWS and cloud computing in general, so I apologize if this question is foolish.
I am currently working on developing an app for Amazon Echo that would allow it to remotely control a PC (i.e. change volume, pause a movie, etc.). My problem is that I do not know how to communicate between my Amazon Lambda service and my Windows Application.
Any ideas?
There are potentially some problems with the way you have posed the question -- how to communicate between a Lambda Function and a Windows machine could involve a number of different solutions, but what you are looking for (as far as I can tell) is a more specific -- yet simultaneously more generalizable -- solution.
Are you trying to actually make an Alexa skill that users could use, or just something for yourself? It makes a big difference, because for just yourself there are a number of hacky solutions you could implement, like port forwarding and dynamic DNS, which fail dramatically if you try to do them in the real world. You need another component -- some kind of real-time push messaging -- that bridges between an "agent" in your Windows app and requests emitted by your Lambda code.
Your actual problem to solve is not so much how to communicate between AWS Lambda and a Windows Application, but rather one of a need for understanding how a platform like Alexa needs to communicate with a "smart home" device, specifically an entertainment device.
It is a relatively complicated undertaking, because -- fundamentally -- there is no way of communicating directly between Lambda and an arbitrary device out on the Internet. Dynamic IP addresses, network address translation (NAT), firewalls, security considerations, and other factors make it impossible to reliably initiate a connection from a Lambda function (or indeed from any Internet connected device) to any other arbitrary destination device. Most devices (my phone, my Alexa-controlled light switch, my Windows laptop) are running behind a boundary that assumes requests are initiated behind the boundary. When I open web sites, stream video, etc., I initiate the request and the response returns on the channel (often a TCP connection) that I have created, from behind my boundary (e.g. the router in my cable modem) that doesn't allow external initiation of TCP connections. They are bidirectional once established, but must be initiated from inside.
Of course, you can statically "poke a hole" in your router configuration by forwarding a specific TCP port to a specific internal (usually private) IP address, which works as long as your Internet provider doesn't change your IP address, and your internal device doesn't get a new IP address... and there'a UPnP NAT Traversal, which seems like a good solution until you realize that it is also terrible (though for a "hobbyist" application, it could work).
While this is a long and complex topic, the short answer is that Alexa, via Lambda code, is only capable of initiating connections, and your device, wherever it may be, is only capable of initiating connections -- not receiving them... and thus you need some kind of "meet in the middle" solution: something that allows the device to maintain its "connection" to a central "service" that can coordinate the interactions on demand.
For example:
AWS IoT Core is a managed cloud platform that lets connected devices easily and securely interact with cloud applications and other devices. AWS IoT Core can support billions of devices and trillions of messages, and can process and route those messages to AWS endpoints and to other devices reliably and securely. With AWS IoT Core, your applications can keep track of and communicate with all your devices, all the time, even when they aren’t connected.
https://aws.amazon.com/iot-core/
The client initiates the connection (e.g. via a web socket) to the IoT platform, and maintains it, so that when a message arrives at IoT, the service knows how to deliver that message to the client when it's received. ("even when they aren't online" refers to the "device shadow" capability, which allows you to programmatically interact with a proxy for the device, e.g. knowing the last temperature setting of a thermostat, and asking the thermostat to change its set point when the connection is re-established at some future point).
Or, potentially something like this:
Firebase Cloud Messaging (FCM) is a cross-platform messaging solution that lets you reliably deliver messages at no cost.
Using FCM, you can notify a client app that new email or other data is available to sync.
https://firebase.google.com/docs/cloud-messaging/
Both of these potential solutions solve the problem by "knowing how to contact" arbitrary devices, wherever they may be... and I would suggest that this is the core of your actual need.
There are a lot of alternatives for such a "service," including roll-your-own websocket or HTML EventSource implementations with servers... the purpose of this is not product recommendations but rather to give you an idea of what you would need for such a scenario -- an intermediate platform that can be interacted with by the Lambda code, which also knows how to communicate with "agent" code running on the device... because both Lambda and the agent need to initiate the communication channels and thus additional components are required to bridge them together.
I want to create a C++ application that can be used (in part) to communicate between users on a local area network using UDP. Each instance of the application will have a thread dedicated to listening for other instances of the application and broadcasting its presence to other instances.
Is there a reliable way to perform this type of broadcast/listening on the LAN using pure C++ and POSIX system calls? I know there's no generally reliable way to find all IPs on a LAN, but I assume this is only because other devices are not willing to respond to pings.
Don't re-invent the wheel. There are two existing technologies, that, when combined, solve your problem in a standardized, well-designed, proven manner:
RFC6762 mDNS (Multicast DNS) is a protocol that works almost exactly like DNS, except it works using IP multicast. Instead of sending your DNS request to a unicast address, you send your DNS request to a multicast group, and any member of that group can answer your request (so you may get multiple answers).
RFC6763 DNS-SD (DNS-based Service Discovery) is a way to encode Services as DNS entries, which allows you then to retrieve Services from DNS using specially encoded hostnames. (For example, looking up the hostname _ipp._tcp.example.com would return a list of all printers that support the Internet Printing Protocol over TCP within the domain example.com)
So, we have one protocol that allows us to ask DNS about Services, and we have one protocol that allows us to ask a group of hosts to answer DNS queries … when we put the two together, we get a way of asking hosts for services! The combination of those two protocols is sometimes called Zeroconf networking, and is already implemented in macOS, iOS, tvOS, and watchOS (where it is called Bonjour), Android, most Unices (via Avahi, a portable implementation of those two protocols), and many home devices such as TVs. E.g. Spotify Connect, ChromeCast, Philips Hue and many others are also based on it. It's how iTunes devices find each other on the local network, for example.
Unfortunately, support in Windows is still limited, at the moment it seems to only exist for Windows 10 apps implemented in ECMAScript. (However, nothing stops you from shipping your own implementation with your app, and AFAIK, both Avahi and Apple's mDNSResponder work on Windows.)
So, what you would basically do is to send an mDNS query to the mDNS multicast group and ask for _myprotocol._udp.local. Then, assuming that your application registers itself with the OS's mDNS service (i.e. Bonjour on macOS, Avahi on Unices, …), you would get back a list of all hosts on the local network that support your protocol.
I'm creating a WiFi program for Windows, I'm new to network programming.
I'm using the Native Wifi API to get information about a network but now I want information about the other devices that are connected to a network.
Does anybody know what I should learn to accomplish this? Do I need to use winsock?
You can do this via UPnP (assuming your AP supports UPnP, but most do).
You'd connect to the WLANConfiguration service of your UPnP access point, and read the TotalAssociations to get the number of associated devices, and the AssociatedDeviceMACAddress and/or AssociatedDeviceIPAddress variables to get the addresses of the associated devices. The latter might give you IPv4 or IPv6 addresses, or it might give you host names.
The TotalAssociations variable is "evented", which means you can have the access point tell you want the number of associated devices changes, and re-enumerate their addresses when that happens.
Microsoft also provides a UPnP API that may be helpful (though I've never used it personally, so I can't say much more about it).
References
UPnP Architecture specification
WLAN Configuration Service specification
I would like to implement the server side of a licence management software. I use C++ in LINUX OS.
When the software starts it must connect to a server that checks privileges and allows/disallow running of some features.
My question is about the implementation of the communication between client and server across internet:
The server will have a static IP on internet so is it enough to use a simple TCP/IP socket client that will connect to a TCP/IP socket server ( providing IP/PORT) ?
I am familiar with socket communication , but less with communication across internet so my question is whether this is the right approach or do I need to use a different mechanism like a http client server or other.
Regards
AFG
Here are some benefits to using HTTP as a transport:
easier to get right, more likely to work in production: Yes, you will probably have to add additional dependencies to deal with HTTP (client and server side), but it's still preferable to yet another homegrown protocol, which you have to implement, maintain, care about backwards compatibility, deal with multiplatform issues (eg. endianness), etc. In terms of implementation ease, using an HTTP based solution should be far easier in the common case (especially true if you build a REST style service API for license checking).
More help available: HTTP as the foundation of the web is one of the most widely used technologies today. Most (all?) problems you will run into are probably publicly documented with solutions/workarounds.
Encryption 'for free': Encryption is already a solved problem (HTTPS/SSL), both with regard to transport as well as with regard to what you have to implement on your end, and it's just a matter of setting it up.
Server Authentication 'for free': HTTPS/SSL doesn't only solve encryption but also server authentication, so that the client can verify whether it's actually talking to the right service.
Guaranteed to work on the internet: HTTP/HTTPS traffic is common on the internet, so you won't run into routing problems or firewalls which are hard to traverse. This might be a problem when using your own protocol.
Flexibility out of the box: You also put less constraints on clients communicating with your server, as it's very simple to build a client in many different environments, as long as they can talk HTTP (and maybe SSL), and they know how to issue the request to your server (ie. what your service API looks like).
Easy to integrate with administrative webapp: If you want to allow users to manage their accounts associated with licenses in some way (update contact info etc.), then you might even combine the license server with that application. You can also build the license administration UI part into the same app if that's useful.
And as a last remark (this puts additional constraints on your client side HTTPS/SSL implementation): you can even use client side SSL certificates, which essentially allow authenticating the client to the server. Depending on how you use them, client side certificates are harder to manage, but they can be eg. expired, or revoked, so to some extent they actually are licenses (to connect to the server).
HTTP is not a different mechanism. It is a protocol operated over TCP/IP connections.
Internet uses IP transport exclusively. You can use UDP, TCP or SCTP session (well, UDP is not much of a session) layer on top of it. TCP is the general choice.
Sockets are operating system interface. They are the only interface to network in most systems, but some systems have different interface. Nothing to do with the transport itself.
IP addresses are in practice tied to network topology, so I strongly discourage hardcoding the IP address into the server. If you have to change network provider for any reason, you won't be getting the same IP address. Use DNS, it's just one gethostbyname call.
And don't forget to authenticate the server; even with hardcoded IP it's too easy to redirect it.
Windows knows when you have removed the network cable from your NIC. Is there a programmatic way to determine this via API in C++?
Note: I am not using .NET and this is for a closed LAN (not connected to Internet ever)
Raymond Chen blogged about something similar recently. Here is the relevant documentation. I think the MIB_IPADDR_DISCONNECTED flag is what you are looking for.
Use the Network List Manager api with the INetwork api.
You can register your app to receive callbacks when networks become connected/not connected.
Or you can get the list of networks and then check each of them to see if the machine is network connected or not
Remember that a windows machine will often have multiple networks set up (Ethernet, wifi, etc)
Remember that just because a network is connected, you may not have access to the internet. Eg you could have DNS or routing problems. Or you could be on a working network that is not connected to the internet.
Due to the above, many diagnostic tools also connect to a "known-good" internet server if they want to really know if they're connected or not. Something like google.com -- they spend a lot of money to make sure that their site is up all the time.
Finally, you can also have a semi-connected situation where packets are getting through but not enough to really enable communications to flow. To test this, don't just ping an internet site since that'd only be a pair of packets. Instead, open a TCP connection or something more than a ping.