delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2002/04/29/11:35:07

Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
Message-ID: <3CCD676A.1080006@jmpax.demon.co.uk>
Date: Mon, 29 Apr 2002 16:31:54 +0100
From: Richard Lewis <richard AT jmpax DOT demon DOT co DOT uk>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:0.9.4) Gecko/20011019 Netscape6/6.2
X-Accept-Language: en-us
MIME-Version: 1.0
To: cygwin AT cygwin DOT com
Subject: Cygwin setsockopt calls winsock 1 implementation

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/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019