Cygwin setsockopt calls winsock 1 implementation

Richard Lewis richard@jmpax.demon.co.uk
Mon Apr 29 08:49:00 GMT 2002


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/



More information about the Cygwin mailing list