How to discover all other instances of my application on the local Windows network? - c++

We want to add a 'collaborative' feature to our application, so our program should be able to automatically discover all other instances of itself that are running on the same local network, without needing any extra configuration from the users.
Our application runs on Windows, so it can use any APIs provided by the OS. We are assuming a network typical for a small business, a couple of Windows PCs, some routers, etc.
Also, will there be problems with anti-viruses, firewalls, and such? We don't want to scare our users.

You can send broadcast packets for that but that only works within a single subnet (actually apparently a "broadcast domain" but it's usually the subnet). If you just try every IP you can think of you might trigger firewall pop-ups that suggest that your software is trying to hack the computer. I think the best way is to use broadcast for the current subnet and offer a user interface for adding other hosts.

Related

C++ application: discover other IPs on LAN

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.

Is it possible to hide the local network traffic of an application from the system and other applications that may be checking?

And oppositely, how much information can an application gather about local network traffic?
And how can one restrict such behavior so that any application trying to check it will come up with nothing?
The application uses a socket connection to communicate with another computer on the network.
Also, I'm talking strictly about the Windows platform, 7 and up.
Unless your application can run at a higher privilidge level than the network service (which I doubt, because this means you can gain unrestricted access to the network device),
not,
the only thing you can try is using an already running application as disguise and use it's networking capabilities.

C/C++ detect network type

I need to write a win32 c/c++ application which will be able to determine whether the PC it's running on is connected to one of 2 networks. The first network is the company LAN (which has no internet connection) and the second network is a standalone switch with a single PC connected to it (the PC that the program is running on).
I'm pretty new to network programming but so far I have tried testing to see if a network drive which is held on our LAN can be mapped. This works fine if the PC is connected to the LAN, the drive mapping succeeds so so LAN detection is successful. However, if the PC is connected to the switch, this results in a VERY long timeout which is not a suitable as it will delay the program so much as to make it unusable.
Does anyone have any alternative suggestions?
I'm using c/c++ in VS 6.0
[Update]
Whilst trying a few different ideas and looking at some of the suggestions below I thought I should update with some additional information as many (if not all) of the suggestions I don't think will work.
(1) The aforementioned LAN has no external connections at all, it is completely isolated so no resolving of external DNS or pinging websites is possible.
(2) Hostname, MAC address, IP, Default Gateway, Subnet etc etc (basically everything you see in ipconfig -all) are all manually configured (not dynamic from the router) so checking any of these settings will return the same whether connected to the LAN or the switch.
(3) Due to point (2), any attempts to communicate with the switch seem to be unsuccessful, in fact almost all networking commands (ping, arp etc) seem to fail - I think due to the machine trying to connect to the LAN when it isn't there :-(
One thing I have found which works is pinging the default gateway IP which times out when connected to the switch. This is sort of ok as I can reduce the timeout of ping so it doesn't just hang for ages but it feels like a bit of a hack and I would certainly appreciate any better solutions.
Thanks
As far as TCP/IP is concerned there is no such thing as a LAN on WAN. There are a set of non-internet routable addresses like 192.168.x.x and 10.x.x.x but these are sometimes used by ISP short of IP addresses.
You best bet is to use Asynchronous APIs when making TCP/IP connections. WIN32 defines a whole buch of OVERLAPPED APIs for this purpose. This will prevent your application from grinding to a halt while waiting for a remote connection.
Alternatively put the socket stuff into another thread and then only notify the UI when the operation is done.
I would first try to differentiate between the two using information available locally--that is, from your computer. Does the output of ipconfig /all differ depending on which network you're connected to? If so, exploit that difference if you can.
Is it possible to get the MAC address of the standalone switch? Of the switch that controls the company LAN? That would be a sure way to tell. Unless somebody cloned the MAC address.
If you try using the existence or non-existence of some network service to determine which network you're connected to, you can never be sure. For example, if you failed to map that network drive, all you know is that the network drive isn't available. You can't say for certain that you're not connected to the company LAN. Same is true if you use ping. Lack of response from a particular machine means only that the machine didn't respond.
Various things you can look at for differentiation:
DNS domain name (GetComputerNameEx)
MAC address of gateway (ping it, then GetIpNetTable)
Routing table(do you have a gateway and default route on the company LAN)
WNet discovered network resources (WNetOpenEnum, WNetEnumResource)
Ability to resolve external hostnames (try a 5-10 names like www.google.com, www.microsoft.com and so on, if one resolves you should have internet)
You'll have to decide how many indicators are "enough" to decide you're on one or the other LAN though if tests fail. Then keep retrying until you have a definite result.
http://msdn.microsoft.com/en-us/library/aa366071%28v=VS.85%29.aspx has a lot of network related functions that you can experiment with to create further indicators.

Blocking all Windows Internet access from a Win32 app

What would be the simplest way for an application I'm writing to block all Internet access on a Windows machine?
More details:
Windows: XP or higher
Application: A basic Win32 app written in C/C++.
Blocking: It needs to be able to block and unblock at will, ideally in a way that the user can't easily reverse. (By, say, right clicking on a network connection icon in the system tray.) Also, ideally, I'd like the method it uses to allow access to be restored should the user restart Windows or reset the machine, though I'd also be willing to have the app auto launch with Windows and unblock access upon startup if the machine was reset while in a blocked state.
Internet access: Primarily, I'd like to block conventional browsers from hitting conventional http/https sites. Secondarily, it would be nice to block IM clients and client-side social networking apps. It would also be nice, but not required, to still allow local networking for file sharing, etc. (Note that only the first requirement is absolute.)
Final notes: This is not meant to be a security utility, nor will its relationship to the user be adversarial (as, for example, with a parental control utility) so it's not important for it to use a scheme that can't be worked around by a determined user. (Consider that I intend for a reboot or reset to clear the blocking. This means that any workaround a user might discover that would take more effort than this is okay.)
Thanks!
p.s. I suspect that the Windows Firewall API won't work for me because this needs to work for users that haven't enabled the firewall or don't have admin privileges, but I'll be thrilled if I'm corrected on this.
It sounds like you're intending to run applications that you don't want to access the internet. Perhaps you could run them inside a virtual machine such as VirtualBox with networking disabled.
You could do it with a Winsock SPI. The Windows SDK has a sample (under Samples\netds\winsock\lsp) which implements what is called a layered service provider which allows you to hook all the user mode functions provided by Winsock and reject/modify the calls to block network access or redirect traffic to different locations. All installed winsock applications will be affected, so in your code you could have policys for what applications can go out and the like and disabled/enable on the fly. Now a determined person could find ways around this but it would be a pain.
That said this isn't trivial to do but the sample should get you most of the way there.
You cannot effectively or practically write your tool with only a user mode application.
What you need to write is a network I/O stack filter driver. This done by writing a Windows Driver. This is different from a Windows Win32 application. Drivers run in kernel mode and applications run in user mode.
On Windows Vista and later, the kernel mode Network Programming Interface (NPI) is designed for this. This is the same API that Windows Firewalls use. These are sometimes called the Winsock kernel (WSK) APIs.
In effect, you are writing a network firewall (more or less)
here are some links
Introduction to Winsock Kernel (WSK)
Windows Core Networking Blog
The Network Programming Interface Docs on MSDN
Note, your will likely need at least two components
Your driver
A Graphical application that a person can use to control your tool
If you want to do any monitoring, you will likely need a user mode service that collects data from your driver. This works better than trying to do this in the driver. In general, you should do the minimal amount of work in the driver.
A few notes:
You need to be very conscious of security when writing this kind of software. This is very much non trivial. Software that is network facing has the highest security requirements.
Be cognizant of performance.
Your driver and/or service must be aware of the context of a calling application. This is also a security boundary. For example, an application not running as administrator should not be able to control your driver.
take a look at firewall sourcecodes

How do you block selected applications from accessing the internet (C++, Win32)

I want to have an application or service that is running that, on some schedule, can disable access to the internet for all applications except for specific ones.
I'm trying to create a filter that can be turned on or off under programmatic control. Not just IP addresses and ports, but I want to be able to block specific applications as well, much like Zone Alarm and other software firewalls let you block.
For example, iexplore.exe, skype.exe, firefox.exe, aim.exe. But still need to allow other applications to connect as needed.
It has to work on Vista as well as XP, but I kind of expect that the method will be different on each of those platforms.
Basically, the filter has to tie the network communication back to the executable that is making the request and then allow or deny it.
Update:
On Vista at least, it looks like I want to use filters in the ALE layers of the WFP.
On XP, I'm still looking for the best way to do it. Do I really need to be writing device drivers and dealing with kernel stuff? I'm just a lowly application developer. Kill me now.
Update 2:
Currently looking at the PfCreateInterface and related Pf* API's for pre-Vista systems.
You can change both Vista and XP's firewall policies dynamically using the INetFwAuthorizedApplications interface from the Windows Firewall API.
Also see this question.
You'll have to write a device driver that filters traffic based on the executable requesting the traffic.
by limiting its access to internet using firewall. go to firewall setting advanced tab (win 7)
and do that
I'm not sure, but I think you'd need to do it by getting the program to run as a user that has limited permissions, the question is, can you make a user account that stops such things?
You'll need to redirect all (or at least many) calls to the WinSock API functions of any running program to your own replacement functions. That means getting into the memory of each running program and hijacking those functions, which is an... interesting... exercise. :-)
That might be enough of a pointer to get you started, or at least to suggest some more specific questions to ask.
Could you move aside (ie rename) the system's winsock DLL and replace it with your own ?
Yours should provide the same API, but check the the process name of incoming requests... return an error code to blocked applications and forward the calls from allowed apps onto the real DLL.