Home | History | Annotate | Download | only in Modules
      1 /* Socket module header file */
      2 
      3 /* Includes needed for the sockaddr_* symbols below */
      4 #ifndef MS_WINDOWS
      5 #ifdef __VMS
      6 #   include <socket.h>
      7 # else
      8 #   include <sys/socket.h>
      9 # endif
     10 # include <netinet/in.h>
     11 # if !defined(__CYGWIN__)
     12 #  include <netinet/tcp.h>
     13 # endif
     14 
     15 #else /* MS_WINDOWS */
     16 # include <winsock2.h>
     17 /* Windows 'supports' CMSG_LEN, but does not follow the POSIX standard
     18  * interface at all, so there is no point including the code that
     19  * attempts to use it.
     20  */
     21 # ifdef PySocket_BUILDING_SOCKET
     22 #  undef CMSG_LEN
     23 # endif
     24 # include <ws2tcpip.h>
     25 /* VC6 is shipped with old platform headers, and does not have MSTcpIP.h
     26  * Separate SDKs have all the functions we want, but older ones don't have
     27  * any version information.
     28  * I use SIO_GET_MULTICAST_FILTER to detect a decent SDK.
     29  */
     30 # ifdef SIO_GET_MULTICAST_FILTER
     31 #  include <MSTcpIP.h> /* for SIO_RCVALL */
     32 #  define HAVE_ADDRINFO
     33 #  define HAVE_SOCKADDR_STORAGE
     34 #  define HAVE_GETADDRINFO
     35 #  define HAVE_GETNAMEINFO
     36 #  define ENABLE_IPV6
     37 # else
     38 typedef int socklen_t;
     39 # endif /* IPPROTO_IPV6 */
     40 #endif /* MS_WINDOWS */
     41 
     42 #ifdef HAVE_SYS_UN_H
     43 # include <sys/un.h>
     44 #else
     45 # undef AF_UNIX
     46 #endif
     47 
     48 #ifdef HAVE_LINUX_NETLINK_H
     49 # ifdef HAVE_ASM_TYPES_H
     50 #  include <asm/types.h>
     51 # endif
     52 # include <linux/netlink.h>
     53 #else
     54 #  undef AF_NETLINK
     55 #endif
     56 
     57 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
     58 #include <bluetooth/bluetooth.h>
     59 #include <bluetooth/rfcomm.h>
     60 #include <bluetooth/l2cap.h>
     61 #include <bluetooth/sco.h>
     62 #include <bluetooth/hci.h>
     63 #endif
     64 
     65 #ifdef HAVE_BLUETOOTH_H
     66 #include <bluetooth.h>
     67 #endif
     68 
     69 #ifdef HAVE_NET_IF_H
     70 # include <net/if.h>
     71 #endif
     72 
     73 #ifdef HAVE_NETPACKET_PACKET_H
     74 # include <sys/ioctl.h>
     75 # include <netpacket/packet.h>
     76 #endif
     77 
     78 #ifdef HAVE_LINUX_TIPC_H
     79 # include <linux/tipc.h>
     80 #endif
     81 
     82 #ifdef HAVE_LINUX_CAN_H
     83 #include <linux/can.h>
     84 #endif
     85 
     86 #ifdef HAVE_LINUX_CAN_RAW_H
     87 #include <linux/can/raw.h>
     88 #endif
     89 
     90 #ifdef HAVE_LINUX_CAN_BCM_H
     91 #include <linux/can/bcm.h>
     92 #endif
     93 
     94 #ifdef HAVE_SYS_SYS_DOMAIN_H
     95 #include <sys/sys_domain.h>
     96 #endif
     97 #ifdef HAVE_SYS_KERN_CONTROL_H
     98 #include <sys/kern_control.h>
     99 #endif
    100 
    101 #ifndef Py__SOCKET_H
    102 #define Py__SOCKET_H
    103 #ifdef __cplusplus
    104 extern "C" {
    105 #endif
    106 
    107 /* Python module and C API name */
    108 #define PySocket_MODULE_NAME    "_socket"
    109 #define PySocket_CAPI_NAME      "CAPI"
    110 #define PySocket_CAPSULE_NAME   PySocket_MODULE_NAME "." PySocket_CAPI_NAME
    111 
    112 /* Abstract the socket file descriptor type */
    113 #ifdef MS_WINDOWS
    114 typedef SOCKET SOCKET_T;
    115 #       ifdef MS_WIN64
    116 #               define SIZEOF_SOCKET_T 8
    117 #       else
    118 #               define SIZEOF_SOCKET_T 4
    119 #       endif
    120 #else
    121 typedef int SOCKET_T;
    122 #       define SIZEOF_SOCKET_T SIZEOF_INT
    123 #endif
    124 
    125 #if SIZEOF_SOCKET_T <= SIZEOF_LONG
    126 #define PyLong_FromSocket_t(fd) PyLong_FromLong((SOCKET_T)(fd))
    127 #define PyLong_AsSocket_t(fd) (SOCKET_T)PyLong_AsLong(fd)
    128 #else
    129 #define PyLong_FromSocket_t(fd) PyLong_FromLongLong((SOCKET_T)(fd))
    130 #define PyLong_AsSocket_t(fd) (SOCKET_T)PyLong_AsLongLong(fd)
    131 #endif
    132 
    133 /* Socket address */
    134 typedef union sock_addr {
    135     struct sockaddr_in in;
    136     struct sockaddr sa;
    137 #ifdef AF_UNIX
    138     struct sockaddr_un un;
    139 #endif
    140 #ifdef AF_NETLINK
    141     struct sockaddr_nl nl;
    142 #endif
    143 #ifdef ENABLE_IPV6
    144     struct sockaddr_in6 in6;
    145     struct sockaddr_storage storage;
    146 #endif
    147 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
    148     struct sockaddr_l2 bt_l2;
    149     struct sockaddr_rc bt_rc;
    150     struct sockaddr_sco bt_sco;
    151     struct sockaddr_hci bt_hci;
    152 #endif
    153 #ifdef HAVE_NETPACKET_PACKET_H
    154     struct sockaddr_ll ll;
    155 #endif
    156 #ifdef HAVE_LINUX_CAN_H
    157     struct sockaddr_can can;
    158 #endif
    159 #ifdef HAVE_SYS_KERN_CONTROL_H
    160     struct sockaddr_ctl ctl;
    161 #endif
    162 } sock_addr_t;
    163 
    164 /* The object holding a socket.  It holds some extra information,
    165    like the address family, which is used to decode socket address
    166    arguments properly. */
    167 
    168 typedef struct {
    169     PyObject_HEAD
    170     SOCKET_T sock_fd;           /* Socket file descriptor */
    171     int sock_family;            /* Address family, e.g., AF_INET */
    172     int sock_type;              /* Socket type, e.g., SOCK_STREAM */
    173     int sock_proto;             /* Protocol type, usually 0 */
    174     PyObject *(*errorhandler)(void); /* Error handler; checks
    175                                         errno, returns NULL and
    176                                         sets a Python exception */
    177     _PyTime_t sock_timeout;     /* Operation timeout in seconds;
    178                                         0.0 means non-blocking */
    179 } PySocketSockObject;
    180 
    181 /* --- C API ----------------------------------------------------*/
    182 
    183 /* Short explanation of what this C API export mechanism does
    184    and how it works:
    185 
    186     The _ssl module needs access to the type object defined in
    187     the _socket module. Since cross-DLL linking introduces a lot of
    188     problems on many platforms, the "trick" is to wrap the
    189     C API of a module in a struct which then gets exported to
    190     other modules via a PyCapsule.
    191 
    192     The code in socketmodule.c defines this struct (which currently
    193     only contains the type object reference, but could very
    194     well also include other C APIs needed by other modules)
    195     and exports it as PyCapsule via the module dictionary
    196     under the name "CAPI".
    197 
    198     Other modules can now include the socketmodule.h file
    199     which defines the needed C APIs to import and set up
    200     a static copy of this struct in the importing module.
    201 
    202     After initialization, the importing module can then
    203     access the C APIs from the _socket module by simply
    204     referring to the static struct, e.g.
    205 
    206     Load _socket module and its C API; this sets up the global
    207     PySocketModule:
    208 
    209     if (PySocketModule_ImportModuleAndAPI())
    210         return;
    211 
    212 
    213     Now use the C API as if it were defined in the using
    214     module:
    215 
    216     if (!PyArg_ParseTuple(args, "O!|zz:ssl",
    217 
    218                           PySocketModule.Sock_Type,
    219 
    220                           (PyObject*)&Sock,
    221                           &key_file, &cert_file))
    222         return NULL;
    223 
    224     Support could easily be extended to export more C APIs/symbols
    225     this way. Currently, only the type object is exported,
    226     other candidates would be socket constructors and socket
    227     access functions.
    228 
    229 */
    230 
    231 /* C API for usage by other Python modules */
    232 typedef struct {
    233     PyTypeObject *Sock_Type;
    234     PyObject *error;
    235     PyObject *timeout_error;
    236 } PySocketModule_APIObject;
    237 
    238 #define PySocketModule_ImportModuleAndAPI() PyCapsule_Import(PySocket_CAPSULE_NAME, 1)
    239 
    240 #ifdef __cplusplus
    241 }
    242 #endif
    243 #endif /* !Py__SOCKET_H */
    244