This is a follow-up to the thread "Wierdness of WSASendTo()??" from a few weeks ago: http://sources.redhat.com/ml/cygwin/2002-04/msg00675.html
I have been looking into porting Unix traceroute to Win32/Cygwin. The thread above discusses problems sending raw packets using a SOCK_RAW socket, Win2k insists on wrapping your raw packet in its own IP header (which rather defeats the purpose of using a raw socket). setsockopt(...IP_HDRINCL...) seems to have no effect. After much experimentation I think I have found the problem. In the cygwin source Win32 setsockopt() and getsockopt() are both explicitly loaded from wsock32.dll. If you inspect the export tables of wsock32.dll and ws2_32.dll on W2K you will find that nearly all entry points into wsock32.dll are passed through to ws2_32.dll, all except: setsockopt getsockopt recv recvfrom What is happening is clear from this kb article: http://support.microsoft.com/default.aspx?scid=kb;en-us;Q257460 between winsock 1.1 and 2.0 M$ changed their IP_XXX defines. It seems the set/getsockopt functions from wsock32 understand the Winsock 1.1 defines and those from ws2_32.dll understand those for Winsock2. I hacked Unix traceroute (with the GRE patch) to call my own home brew ws2setsockopt(...,IP_HDRINCL,...) which called the function exported from ws2_32.dll. Win2k started sending raw packets as it should. One oddity, even with my own ws2getsockopt() I could never successfully read IP_HDRINCL. ws2_32.dll getsockopt() kept returning -1 with WSAGetLastError() returning WSAENOPROTOOPT. (Despite this the value returned did seem to be correct but I wouldnt trust it). I encountered another problem while trying to get traceroute running, the select() when reading packets never returned with a received packet. It seems Win32 (or possibly Cygwin) needs the receiving socket to be bound to the local IP address with bind() before it receives raw packets. To be consistent I also rewired recvfrom() to a home brew ws2recvfrom() using the function from ws2_32.dll. Both wsock32 and ws2_32 recvfrom worked fine. This suggests Cygwin supports Winsock 1.1 get/setsockopt. Winsock2 functions can be explicitly called using LoadLibrary and GetProcAddress with ws2_32.dll. Cygwin socket handles must be translated to Win32 handles using get_osfhandle() before calling the ws2_32.dll functions. Note that IP_HDRINCL is rumoured to work only on Win2k and XP, I tested on Win2k only. On NT4 SP6 my traceroute fails with setsockopt(...IP_HDRINCL...)==-1, WSAGetLastError()==WSAENOPROTOOPT. One final thing, raw packets have nasty sharp edges and could hurt the innocent. Please use this information to send raw packets in good causes. Richard Lewis. * This work was carried out pro-bono for Oxfam (www.oxfam.org.uk) under a grant from Pronoia Ltd, Oxford, UK. -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/