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 #else 85 # undef AF_CAN 86 # undef PF_CAN 87 #endif 88 89 #ifdef HAVE_LINUX_CAN_RAW_H 90 #include <linux/can/raw.h> 91 #endif 92 93 #ifdef HAVE_LINUX_CAN_BCM_H 94 #include <linux/can/bcm.h> 95 #endif 96 97 #ifdef HAVE_SYS_SYS_DOMAIN_H 98 #include <sys/sys_domain.h> 99 #endif 100 #ifdef HAVE_SYS_KERN_CONTROL_H 101 #include <sys/kern_control.h> 102 #endif 103 104 #ifdef HAVE_LINUX_VM_SOCKETS_H 105 # include <linux/vm_sockets.h> 106 #else 107 # undef AF_VSOCK 108 #endif 109 110 #ifdef HAVE_SOCKADDR_ALG 111 112 # include <linux/if_alg.h> 113 # ifndef AF_ALG 114 # define AF_ALG 38 115 # endif 116 # ifndef SOL_ALG 117 # define SOL_ALG 279 118 # endif 119 120 /* Linux 3.19 */ 121 # ifndef ALG_SET_AEAD_ASSOCLEN 122 # define ALG_SET_AEAD_ASSOCLEN 4 123 # endif 124 # ifndef ALG_SET_AEAD_AUTHSIZE 125 # define ALG_SET_AEAD_AUTHSIZE 5 126 # endif 127 /* Linux 4.8 */ 128 # ifndef ALG_SET_PUBKEY 129 # define ALG_SET_PUBKEY 6 130 # endif 131 132 # ifndef ALG_OP_SIGN 133 # define ALG_OP_SIGN 2 134 # endif 135 # ifndef ALG_OP_VERIFY 136 # define ALG_OP_VERIFY 3 137 # endif 138 139 #endif /* HAVE_SOCKADDR_ALG */ 140 141 142 #ifndef Py__SOCKET_H 143 #define Py__SOCKET_H 144 #ifdef __cplusplus 145 extern "C" { 146 #endif 147 148 /* Python module and C API name */ 149 #define PySocket_MODULE_NAME "_socket" 150 #define PySocket_CAPI_NAME "CAPI" 151 #define PySocket_CAPSULE_NAME PySocket_MODULE_NAME "." PySocket_CAPI_NAME 152 153 /* Abstract the socket file descriptor type */ 154 #ifdef MS_WINDOWS 155 typedef SOCKET SOCKET_T; 156 # ifdef MS_WIN64 157 # define SIZEOF_SOCKET_T 8 158 # else 159 # define SIZEOF_SOCKET_T 4 160 # endif 161 #else 162 typedef int SOCKET_T; 163 # define SIZEOF_SOCKET_T SIZEOF_INT 164 #endif 165 166 #if SIZEOF_SOCKET_T <= SIZEOF_LONG 167 #define PyLong_FromSocket_t(fd) PyLong_FromLong((SOCKET_T)(fd)) 168 #define PyLong_AsSocket_t(fd) (SOCKET_T)PyLong_AsLong(fd) 169 #else 170 #define PyLong_FromSocket_t(fd) PyLong_FromLongLong((SOCKET_T)(fd)) 171 #define PyLong_AsSocket_t(fd) (SOCKET_T)PyLong_AsLongLong(fd) 172 #endif 173 174 /* Socket address */ 175 typedef union sock_addr { 176 struct sockaddr_in in; 177 struct sockaddr sa; 178 #ifdef AF_UNIX 179 struct sockaddr_un un; 180 #endif 181 #ifdef AF_NETLINK 182 struct sockaddr_nl nl; 183 #endif 184 #ifdef ENABLE_IPV6 185 struct sockaddr_in6 in6; 186 struct sockaddr_storage storage; 187 #endif 188 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H 189 struct sockaddr_l2 bt_l2; 190 struct sockaddr_rc bt_rc; 191 struct sockaddr_sco bt_sco; 192 struct sockaddr_hci bt_hci; 193 #endif 194 #ifdef HAVE_NETPACKET_PACKET_H 195 struct sockaddr_ll ll; 196 #endif 197 #ifdef HAVE_LINUX_CAN_H 198 struct sockaddr_can can; 199 #endif 200 #ifdef HAVE_SYS_KERN_CONTROL_H 201 struct sockaddr_ctl ctl; 202 #endif 203 #ifdef HAVE_SOCKADDR_ALG 204 struct sockaddr_alg alg; 205 #endif 206 #ifdef AF_VSOCK 207 struct sockaddr_vm vm; 208 #endif 209 } sock_addr_t; 210 211 /* The object holding a socket. It holds some extra information, 212 like the address family, which is used to decode socket address 213 arguments properly. */ 214 215 typedef struct { 216 PyObject_HEAD 217 SOCKET_T sock_fd; /* Socket file descriptor */ 218 int sock_family; /* Address family, e.g., AF_INET */ 219 int sock_type; /* Socket type, e.g., SOCK_STREAM */ 220 int sock_proto; /* Protocol type, usually 0 */ 221 PyObject *(*errorhandler)(void); /* Error handler; checks 222 errno, returns NULL and 223 sets a Python exception */ 224 _PyTime_t sock_timeout; /* Operation timeout in seconds; 225 0.0 means non-blocking */ 226 } PySocketSockObject; 227 228 /* --- C API ----------------------------------------------------*/ 229 230 /* Short explanation of what this C API export mechanism does 231 and how it works: 232 233 The _ssl module needs access to the type object defined in 234 the _socket module. Since cross-DLL linking introduces a lot of 235 problems on many platforms, the "trick" is to wrap the 236 C API of a module in a struct which then gets exported to 237 other modules via a PyCapsule. 238 239 The code in socketmodule.c defines this struct (which currently 240 only contains the type object reference, but could very 241 well also include other C APIs needed by other modules) 242 and exports it as PyCapsule via the module dictionary 243 under the name "CAPI". 244 245 Other modules can now include the socketmodule.h file 246 which defines the needed C APIs to import and set up 247 a static copy of this struct in the importing module. 248 249 After initialization, the importing module can then 250 access the C APIs from the _socket module by simply 251 referring to the static struct, e.g. 252 253 Load _socket module and its C API; this sets up the global 254 PySocketModule: 255 256 if (PySocketModule_ImportModuleAndAPI()) 257 return; 258 259 260 Now use the C API as if it were defined in the using 261 module: 262 263 if (!PyArg_ParseTuple(args, "O!|zz:ssl", 264 265 PySocketModule.Sock_Type, 266 267 (PyObject*)&Sock, 268 &key_file, &cert_file)) 269 return NULL; 270 271 Support could easily be extended to export more C APIs/symbols 272 this way. Currently, only the type object is exported, 273 other candidates would be socket constructors and socket 274 access functions. 275 276 */ 277 278 /* C API for usage by other Python modules */ 279 typedef struct { 280 PyTypeObject *Sock_Type; 281 PyObject *error; 282 PyObject *timeout_error; 283 } PySocketModule_APIObject; 284 285 #define PySocketModule_ImportModuleAndAPI() PyCapsule_Import(PySocket_CAPSULE_NAME, 1) 286 287 #ifdef __cplusplus 288 } 289 #endif 290 #endif /* !Py__SOCKET_H */ 291