I am using the sample of given link for ping the given list of IP
http://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio/example/icmp/ping.cpp
when ever i try ping a IP i am getting this exception at the initialization time itself
Exception open: An attempt was made to access a socket in a way forbidden by its access permissions
What causing this problem?
i am running it on windows 7 64 bit
For security reasons, some systems limit the use of raw sockets to users with administrator permissions. Boost.Asio's ICMP socket implementation uses raw sockets, and thus requires the application to run with administrator permissions. The Windows documentation states:
Raw sockets offer the capability to manipulate the underlying transport, so they can be used for malicious purposes that pose a security threat. Therefore, only members of the Administrators group can create sockets of type SOCK_RAW on Windows 2000 and later.
Windows provides an IcmpSendEcho() family of functions that can be used to send and handle ICMP echo request/response without requiring administrative permissions, as the raw sockets are not exposed.
Related
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.
Windows 8 and above has setting to make a Wi-Fi (and other) connection to be metered (and have cost attached to it, but irrelevant here). I've used Native Wi-Fi API and WCM APIs to find required information.
With sockets, it is possible to bind, selectively send, and ignoring incoming packets from/to the metered-connection. But, how to do this with WinHTTP APIs?
Some answers on StackOverflow and SuperUser suggest using ForceBindIP, but we cannot simply use it.
If MS Windows has implemented metered connections, ideally there should be some approach to instruct WinHTTP services to not to use specific connections.
Unfortunately, neither WinInet nor WinHTTP natively support what you are asking for.
You would likely have to resort to using the WinSock API bind() function to manually bind a WinInet/WinHTTP session socket to the desired network connection.
Prior to Windows 7, you could get a SOCKET handle from an HINTERNET handle by using InternetQueryOption() with the INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO option. It fills an INTERNET_DIAGNOSTIC_SOCKET_INFO struct with information about the connection, including the actual SOCKET handle.
However, this option is no longer supported in Windows 7 and later. And while it might be possible to track down the SOCKET handle manually with some extra work, I don't think it would do you any good. A socket needs to be bound with bind() before it attempts to connect to a server. The relevant information provided by WinInet/WinHTTP that could be used to hunt down the SOCKET handle is not made available until the connect attempt is in progress. Just prior to connecting, the info is not in the TCP routing tables yet. And one connected, it is too late to re-bind the socket.
So I think you are out of luck on this, unless/until Microsoft exposes a new API to support binding WinInet/WinHTTP sessions, or otherwise expose access to the SOCKET handle again.
I am looking forward for an example for using a user defined control code in services. I want to send a user defined command to my windows service. At this command windows service will create a named-pipe for client process, and client will establish a connection with this named-pipe by CreateFile function. My custom control sometimes works well but later it shows error for invalidation.
So how can I establish information exchange between a service and various clients?
SERVICE_USER_DEFINED_CONTROL is rarely used. When it is used, it is generally to prompt the service to re-read its configuration file. (On unix SIGHUP is generally used for the same purpose).
In your case the correct answer is to simply create the named pipe on startup and keep listening, and wait for someone to connect if they ever do.
Is there any way in C++ on windows to monitor a program and redirect any outgoing requests it makes on a specific port? I have a simple C++ http proxy and want it to be able to automatically redirect all browser requests on port 80 through itself.
The simple way to do it is to create a Windows kernel hook to trap socket requests and reroute them to your proxy.
Some useful documentation on this is:
http://www.internals.com/articles/apispy/apispy.htm
If you're using Windows Vista or better, consider Windows Filtering Platform (WFP):
http://www.microsoft.com/whdc/device/network/wfp.mspx
Also consider looking at Detours (commercial) and EasyHook (free). They significantly simplify the process of writing hooks and redirecting API calls (both Win32 and Application).
The program would have to be run with administrative privileges in kernel mode of the host OS.
While I don't have extensive experience with windows kernel hooks, in BSD and linux its trivial to install a kernel module that over-writes the system calls for creating sockets and could easily redirect all sockets to a proxy socket of choice.
If you mean [any destination port] to [one port] then you will have to rely on special drivers. The problem with windows is the inability to natively block [drop] packets. For example a common solution is winpcap. However, while you can monitor traffic, you cannot stop the traffic or modify it in a useful way.
On windows the only solution I've seen would be to use some open TUN/TAP adapter. With that, you would be able to modify every packet that leaves your system.
If you know beforehand the destination port you will be using then it gets rather simple. Simply write a passthrough c++ socket program that will only change the destination port.
If you want to redirect browser requests then you can simply edit the settings in your browser.
Is there an existing Linux/POSIX C/C++ library or example code for how to rebind a socket from one physical interface to another?
For example, I have ping transmitting on a socket that is associated with a physical connection A and I want to rebind that socket to physical connection B and have the ping packets continue being sent and received on connection B (after a short delay during switch-over).
I only need this for session-less protocols.
Thank you
Update:
I am trying to provide failover solution for use with PPP and Ethernet devices.
I have a basic script which can accomplish 90% of the functionality through use of iptables, NAT and routing table.
The problem is when the failover occurs, the pings continue being sent on the secondary connection, however, their source IP is from the old connection.
I've spoken with a couple of people who work on commercial routers and their suggestion is to rebind the socket to the secondary interface.
Update 2:
I apologise for not specifying this earlier. This solution will run on a router. I cannot change the ping program because it will run on the clients computer. I used ping as just an example, any connection that is not session-based should be capable of being switched over. I tested this feature on several commercial routers and it does work. Unfortunately, their software is proprietary, however, from various conversations and testing, I found that they are re-binding the sockets on failover.
As of your updated post, the problem is that changing the routing info is not going to change the source address of your ping, it will just force it out the second interface. This answer contains some relevant info.
You'll need to change the ping program. You can use a socket-per-interface approach and somehow inform the program when to fail over. Or you will have to close the socket and then bind to the second interface.
You can get the interface info required a couple of ways including calling ioctl() with the SIOCGIFCONF option and looping through the returned structures to get the interface address info.
I do't think that's quite a well-defined operation. the physical interfaces have different MAC addresses, so unless you have a routing layer mapping them (NAT or the like) then they're going to have different IP addresses.
Ports are identified by a triple of <IP addr, Port number, protocol> so if your IP address changes the port is going to change.
What are you really trying to do here?
I'm not at all sure what you're trying to accomplish, but I have a guess... Are you trying to do some kind of failover? If so, then there are indeed ways to accomplish that, but why not do it in the OS instead of the application?
On one end you can use CARP, and on the other you can use interface trunking/bonding (terminology varies) in failover mode.