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)