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