views:

335

answers:

3

When we send a packet from a udp port we receive an exception if the network returns an ICMP host unreachable. The exception doesn't tell us anything useful (like the contents of the ICMP packet).

No problem, we'll just listen for ICMP and that will give us the info we need, while ignoring the exception on the UDP port. So, open a raw socket, listen for ICMP packets and go from there.

Works fine in development (Win XP) but in production on server 2008 it appears the security context the exe is running in must have admin rights to be able to open a raw socket. This is useless for a service. If I understand what Microsoft are saying then the only way we can do what we want is run our service under an account with admin rights. Feels a bit like sledgehammer for a peanut not to mention a potential security hole that goes with having a network facing service running under an admin account.

I really hope I am wrong here but I can't seem to find anything that contradicts the above.

Anyone got any comments / hints or sympathy?

A: 

Had exactly the same issue myself Listen for ICMP packets in C#. Actually looks like your issue is windows permissions so that post won't help.

One area I was planning on delving into a bit further is to check whether there is anymore information in the SocketException generated by the UdpListener. It just seems unreasonable that as Windows is using the ICMP packet to generate the exception it wouldn't be recording the information in that packet somewhere.

Like you I have not been able to get very far with getting the ICMP info out of the exception information at the .Net level but I want to see if there is anything further that can be obtained with the Win32 API such as GetLastError or some other calls specifically for WinSock32.

sipwiz
Not really the same. We are receiving the ICMP packets and processing them fine under XP, un 2008 we have to run under admin context which bascially means the service can do whatever it wants (or any breaching it can anyway)
Frustrating Developments
Yes sorry, I jumped the gun on my answer. I do know on Windows 2k3 and 2k8 that you cannot use raw sockets unless you have admin rights. Apparently that change was prevent trojans running amok, raw sockets are abused in Windows XP.
sipwiz
You can use raw sockets on 2k3, our service works fine there. So make using raw sockets a right like "run as a service" or "log on remotely" but locking it down to administrator is just dumb! A frustrating and short sighted "solution" to the problem....
Frustrating Developments
A: 

From the MSDN website:

To use a socket of type SOCK_RAW requires administrative privileges. Users running Winsock applications that use raw sockets must be a member of the Administrators group on the local computer, otherwise raw socket calls will fail with an error code of WSAEACCES. On Windows Vista and later, access for raw sockets is enforced at socket creation. In earlier versions of Windows, access for raw sockets is enforced during other socket operations.

To get around this problem in my project , I've created a Windows service that serves as a network proxy for our UI application. The Windows serves runs under the local admin account in order to get around the limitations. The application connects to the service using WCF, telling it what kind of socket to open and what filter(s) to apply. The data is then sent back via callback using Protocol Buffers for encoding (at least that's the plan - the callback part is still in progress).

Matt Davis
It looks like we'll have to do the same but a network facing service running as an administrator? isn't that security 101 - "run at least privilege as possible"? This seems like a knee jerk reaction fix rather than something that was thought about...
Frustrating Developments
In our case, the WCF connection is restricted to local machine access through the NetNamedPipeBinding. In the future, I plan to open this up using NetTcpBinding, at which point, we'll have to be more diligent about security. But WCF allows for that.
Matt Davis
And for what it's worth, yes, this has been an extremely frustrating change by Microsoft. I understand the rationale from their standpoint, but the change hurts the 'good guys' while the 'bad guys' find other ways to circumvent security.
Matt Davis
+1  A: 

Rather than listening for ICMP responses to your failed UDP sends, why not send a brand spanking new ICMP echo request?

When you get the exception, you could PInvoke the IcmpSendEcho() function (from Win32 IP Helper API) to generate a new ICMP echo request yourself. The key bit is that the function returns a buffer with the echo reply in it, including status codes e.g. IP_DEST_HOST_UNREACHABLE.

I don't think you need any special privileges to do this, so it should be easier than listening for ICMP replies with raw sockets.

You will need three functions: IcmpCreateFile(), IcmpSendEcho() and IcmpCloseHandle() - PInvoke.net has the necessary interop details:

http://www.pinvoke.net/default.aspx/icmp/IcmpCreateFile.html http://www.pinvoke.net/default.aspx/icmp/IcmpSendEcho.html http://www.pinvoke.net/default.aspx/icmp/IcmpCloseHandle.html

snowcrash09