[PATCH] Re: IP_MULTICAST_IF et all / Winsock[2] value conflict

Brian Ford Brian.Ford@flightsafety.com
Fri Sep 30 23:39:00 GMT 2005


On Fri, 30 Sep 2005, Corinna Vinschen wrote:
> On Sep 30 10:07, Brian Ford wrote:
> > We can simply translate the current constant Winsock 1 values to Winsock 2
> > ones when necessary in cygwin_[set|get]sockopt.  There are only 8 values
> > that need changing, I think.
>
> Yeah, I think that we can basically do something like this.  But we
> should not try to guess what the application really meant to do
> based on the incoming value and the winsock version in use.

Why not?  There is no guessing involved if we do not change Cygwin's
system headers.  If someone used a Windows header directly and called the
Cygwin [set|get]sockopt, well then..., that's their fault.

> Actually we have two states, applications built before we changed the
> header file and applications built after we changed the header file.

Let's just not change it ;-).

> This is visible by an internal version number maintained by Cygwin.

Ok, I'm not aware of how that works.

> The problem is that the value can be simply wrong today, because the
> application is built against the old (wrong) header file, but running
> under a Cygwin which is run-time loading Winsock2.  Anyway, the idea
> to convert the incoming values based on some internal information is
> a good one.

Ok, here's an untested (as yet) patch:

2005-09-30  Brian Ford  <Brian.Ford@FlightSafety.com>

	* net.cc (ws2ip_optname): New function to convert IP_* socket
	options from Winsock 1.1 values to Winsock 2 ones.
	(cygwin_setsockopt): Use it.
	(cygwin_getsockopt): Likewise.

> I want to drop Winsock1 support nevertheless.  It only complicates the
> code and has no real gain.

I think I'll let you handle that one ;-).

> Yup, that's something for 1.5.20 or, more likely 1.5.21.  We can discuss
> implementation details on cygwin-developers.

I was hoping this would be simple enough that it might make it in before,
but it's obviously up to you and cgf to decide.

-- 
Brian Ford
Senior Realtime Software Engineer
VITAL - Visual Simulation Systems
FlightSafety International
the best safety device in any aircraft is a well-trained pilot...
-------------- next part --------------
Index: net.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/net.cc,v
retrieving revision 1.194
diff -u -p -r1.194 net.cc
--- net.cc	23 Sep 2005 23:25:25 -0000	1.194
+++ net.cc	30 Sep 2005 23:35:56 -0000
@@ -663,6 +663,59 @@ cygwin_recvfrom (int fd, void *buf, int 
   return res;
 }
 
+/* convert IP_* socket options from Winsock 1.1 to Winsock 2 */
+static int
+ws2ip_optname (int optname)
+{
+  /*
+   * Cygwin's system includes define the IP_* macros in terms of Winsock 1.1
+   * (Winsock.h, wsock32.lib).  In Winsock 2 (Ws2tcpip.h, ws2_32.lib), some
+   * of these macros have redefined values.  The 1.1 values are consistent
+   * with the original ones Steve Deering defined in "IP Multicast Extensions
+   * for 4.3BSD UNIX related systems (MULTICAST 1.2 Release)."  However, these
+   * conflicted with the definitions for some IPPROTO_IP level socket options
+   * already assigned by BSD, so Berkeley changed all the values by adding 7.
+   * The Winsock 2 values are the BSD 4.4 compatible ones that we translate
+   * to here.
+   *
+   * See also: MSDN KB article Q257460
+   * http://support.microsoft.com/support/kb/articles/Q257/4/60.asp
+   * 
+   * Winsock 2 defines              Winsock 1.1 value
+   *
+   * #define IP_TOS             3   // 8
+   * #define IP_TTL             4   // 7
+   * #define IP_MULTICAST_IF    9   // 2
+   * #define IP_MULTICAST_TTL   10  // 3
+   * #define IP_MULTICAST_LOOP  11  // 4
+   * #define IP_ADD_MEMBERSHIP  12  // 5
+   * #define IP_DROP_MEMBERSHIP 13  // 6
+   * #define IP_DONTFRAGMENT    14  // 9
+   */
+
+  switch (optname)
+    {
+      case IP_TOS:
+	optname = 3;
+	break;
+      case IP_TTL:
+	optname = 4;
+	break;
+      case IP_MULTICAST_IF:
+      case IP_MULTICAST_TTL:
+      case IP_MULTICAST_LOOP:
+      case IP_ADD_MEMBERSHIP:
+      case IP_DROP_MEMBERSHIP:
+	optname += 7;
+	break;
+      case IP_DONTFRAGMENT:
+	optname = 14;
+	break;
+    }
+
+  return optname;
+}
+
 /* exported as setsockopt: standards? */
 extern "C" int
 cygwin_setsockopt (int fd, int level, int optname, const void *optval,
@@ -712,7 +765,10 @@ cygwin_setsockopt (int fd, int level, in
     res = -1;
   else
     {
-      res = setsockopt (fh->get_socket (), level, optname,
+      int ws_optname = level == IPPROTO_IP && winsock2_active
+		       ? ws2ip_optname (optname) : optname;
+
+      res = setsockopt (fh->get_socket (), level, ws_optname,
 			(const char *) optval, optlen);
 
       if (optlen == 4)
@@ -782,7 +838,10 @@ cygwin_getsockopt (int fd, int level, in
     }
   else
     {
-      res = getsockopt (fh->get_socket (), level, optname, (char *) optval,
+      int ws_optname = level == IPPROTO_IP && winsock2_active
+		       ? ws2ip_optname (optname) : optname;
+
+      res = getsockopt (fh->get_socket (), level, ws_optname, (char *) optval,
 			(int *) optlen);
 
       if (optname == SO_ERROR)


More information about the Cygwin-patches mailing list