classification
Title: socket module missing IPPROTO_IPV6, IPPROTO_IPV4 on Windows
Type: behavior Stage:
Components: Windows Versions: Python 3.8, Python 3.7
process
Status: open Resolution:
Dependencies: 17561 Superseder:
Assigned To: Nosy List: abrezovsky, christian.heimes, eryksun, giampaolo.rodola, jgosmann, mhils, paul.moore, steve.dower, tim.golden, zach.ware
Priority: normal Keywords: easy (C)

Created on 2017-02-09 18:27 by mhils, last changed 2019-02-19 18:34 by gregory.p.smith.

Messages (8)
msg287449 - (view) Author: Maximilian Hils (mhils) * Date: 2017-02-09 18:27
The latest Windows builds for Python 3.5.3/3.6.0 do not export socket.IPPROTO_IPV6, even though e.g. socket.IPV6_V6ONLY is exported. This seems to be wrong to me as IPV6_V6ONLY requires the corresponding socket option level IPPROTO_IPV6 to be actually useful. The same issue at least also applies to IPPROTO_IPV4.

christian.heimes mentioned that this is intended behaviour in https://bugs.python.org/issue6926 as Windows would not define the constants. Now I am all but an expert on this, but it seems to me that IPPROTO_IPV6 is defined in Windows:
https://msdn.microsoft.com/en-us/library/windows/hardware/ff543746(v=vs.85).aspx. Apologies if I'm missing something here.

Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 07:18:10) [MSC v.1900 32 bit (Intel)] on win32
>>> import socket; socket.IPPROTO_IPV6
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'socket' has no attribute 'IPPROTO_IPV6'

As a workaround, IPPROTO_IPV6 can be substituted with the hardcoded constant 41.
msg287472 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2017-02-10 02:01
The macro is defined but not defined. If I insert the following line before the #ifdef check:

    #define IPPROTO_IPV6 IPPROTO_IPV6

then the constant gets added:

    >>> import _socket
    >>> _socket.IPPROTO_IPV6
    41

The same applies to IPPROTO_IPV4 and probably others.
msg287477 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2017-02-10 07:25
Unless someone has a better (more automated) way to handle the Winsock IPPROTO enum, I suggest we either special-case the individual tests for MS_WINDOWS when we know that Winsock defines the value; or just define macros for the values in the enum:

    #ifdef MS_WINDOWS /* Macros based on the IPPROTO enum. */
    #define IPPROTO_ICMP IPPROTO_ICMP
    #define IPPROTO_IGMP IPPROTO_IGMP
    #define IPPROTO_GGP IPPROTO_GGP
    #define IPPROTO_TCP IPPROTO_TCP
    #define IPPROTO_PUP IPPROTO_PUP
    #define IPPROTO_UDP IPPROTO_UDP
    #define IPPROTO_IDP IPPROTO_IDP
    #define IPPROTO_ND IPPROTO_ND 
    #define IPPROTO_RAW IPPROTO_RAW
    #define IPPROTO_MAX IPPROTO_MAX
    #if (_WIN32_WINNT >= 0x0501)
    #define IPPROTO_HOPOPTS IPPROTO_HOPOPTS
    #define IPPROTO_IPV4 IPPROTO_IPV4
    #define IPPROTO_IPV6 IPPROTO_IPV6
    #define IPPROTO_ROUTING IPPROTO_ROUTING
    #define IPPROTO_FRAGMENT IPPROTO_FRAGMENT
    #define IPPROTO_ESP IPPROTO_ESP
    #define IPPROTO_AH IPPROTO_AH
    #define IPPROTO_ICMPV6 IPPROTO_ICMPV6
    #define IPPROTO_NONE IPPROTO_NONE
    #define IPPROTO_DSTOPTS IPPROTO_DSTOPTS
    #define IPPROTO_ICLFXBM IPPROTO_ICLFXBM
    #endif /* (_WIN32_WINNT >= 0x0501) */
    #if (_WIN32_WINNT >= 0x0600)
    #define IPPROTO_ST IPPROTO_ST
    #define IPPROTO_CBT IPPROTO_CBT
    #define IPPROTO_EGP IPPROTO_EGP
    #define IPPROTO_IGP IPPROTO_IGP
    #define IPPROTO_RDP IPPROTO_RDP
    #define IPPROTO_PIM IPPROTO_PIM
    #define IPPROTO_PGM IPPROTO_PGM
    #define IPPROTO_L2TP IPPROTO_L2TP
    #define IPPROTO_SCTP IPPROTO_SCTP
    #endif /* (_WIN32_WINNT >= 0x0600) */
    #endif /* MS_WINDOWS */

or call PyModule_AddIntConstant(m, "IPPROTO_ICMP", IPPROTO_ICMP) and so on for each enum value.
msg287541 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2017-02-10 14:43
We may just want to copy the values from the enum if there are different versions when they were introduced. But if that's not a problem, adding the MS_WINDOWS check is better than defining new macros.
msg333133 - (view) Author: Andrew Brezovsky (abrezovsky) * Date: 2019-01-07 03:51
Can confirm this is still a problem in latest versions of 3.5, 3.6, and 3.7

Any progress made on this?
msg333727 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2019-01-15 18:37
No progress, but I like the extra defines idea best (directly in socketmodule.c, not in a public header file). That's the easiest way to close the gap between (apparently) real constants used on Windows and the preprocessor defines (apparently) used elsewhere.
msg335924 - (view) Author: Giampaolo Rodola' (giampaolo.rodola) * (Python committer) Date: 2019-02-19 10:44
It turns out having this fix would be useful for proceeding with issue17561, which right now cannot support dual-stack IPv4/6 on Windows because IPPROTO_IPV6 is missing, see my comment:
https://github.com/python/cpython/pull/11784#issuecomment-465078646
msg335929 - (view) Author: Giampaolo Rodola' (giampaolo.rodola) * (Python committer) Date: 2019-02-19 11:44
@eryksun I tried your patch (https://bugs.python.org/issue29515#msg287477) on Windows 10 and it looks good. It introduces the following new constants:

IPPROTO_IGMP
IPPROTO_GGP
IPPROTO_PUP
IPPROTO_IDP
IPPROTO_ND
IPPROTO_MAX
IPPROTO_HOPOPTS
IPPROTO_IPV4
IPPROTO_IPV6
IPPROTO_ROUTING
IPPROTO_FRAGMENT
IPPROTO_ESP
IPPROTO_AH
IPPROTO_ICMPV6
IPPROTO_NONE
IPPROTO_DSTOPTS
IPPROTO_EGP
IPPROTO_PIM
IPPROTO_SCTP

...plus these Windows-only ones for which I had to add an additional PyModule_AddIntMacro() call:

IPPROTO_ICLFXBM
IPPROTO_ST
IPPROTO_CBT
IPPROTO_IGP
IPPROTO_RDP
IPPROTO_PGM
IPPROTO_L2TP

Up 'till now only these ones were exposed:

IPPROTO_ICMP
IPPROTO_TCP
IPPROTO_UDP
IPPROTO_RAW

I think we can proceed with this. Care to provide a patch?
History
Date User Action Args
2019-02-19 18:34:16gregory.p.smithsetversions: + Python 3.8, - Python 3.5, Python 3.6
2019-02-19 11:44:09giampaolo.rodolasetmessages: + msg335929
2019-02-19 10:44:58giampaolo.rodolasetnosy: + giampaolo.rodola
dependencies: + Add socket.bind_socket() convenience function
messages: + msg335924
2019-01-15 18:37:36steve.dowersetkeywords: + easy (C)

messages: + msg333727
2019-01-07 03:51:13abrezovskysetnosy: + abrezovsky
messages: + msg333133
2017-10-30 17:24:15jgosmannsetnosy: + jgosmann
2017-02-10 14:43:15steve.dowersetmessages: + msg287541
2017-02-10 07:25:57eryksunsetmessages: + msg287477
2017-02-10 02:01:49eryksunsetnosy: + eryksun

messages: + msg287472
versions: + Python 3.5, Python 3.7
2017-02-09 18:27:42mhilscreate