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