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