blob: 8d19cbf8d94a83d7fe1fce55d2270f6ba8d72176 [file] [log] [blame]
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +00001/* Socket module header file */
2
3/* Includes needed for the sockaddr_* symbols below */
4#ifndef MS_WINDOWS
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00005#ifdef __VMS
6# include <socket.h>
7# else
8# include <sys/socket.h>
9# endif
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000010# include <netinet/in.h>
Christian Heimesb5daaed2007-11-30 23:34:21 +000011# if !(defined(__CYGWIN__) || (defined(PYOS_OS2) && defined(PYCC_VACPP)))
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000012# include <netinet/tcp.h>
13# endif
14
15#else /* MS_WINDOWS */
Martin v. Löwis272cb402002-03-01 08:31:07 +000016# include <winsock2.h>
17# include <ws2tcpip.h>
Amaury Forgeot d'Arc3d17a5c2008-06-13 01:09:34 +000018/* 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
Martin v. Löwisb072cf22008-06-14 11:59:52 +000020 * any version information.
21 * I use SIO_GET_MULTICAST_FILTER to detect a decent SDK.
Amaury Forgeot d'Arc3d17a5c2008-06-13 01:09:34 +000022 */
Martin v. Löwisb072cf22008-06-14 11:59:52 +000023# ifdef SIO_GET_MULTICAST_FILTER
Amaury Forgeot d'Arc3d17a5c2008-06-13 01:09:34 +000024# 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
31typedef int socklen_t;
32# endif /* IPPROTO_IPV6 */
33#endif /* MS_WINDOWS */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000034
35#ifdef HAVE_SYS_UN_H
36# include <sys/un.h>
37#else
38# undef AF_UNIX
39#endif
40
Martin v. Löwis11017b12006-01-14 18:12:57 +000041#ifdef HAVE_LINUX_NETLINK_H
Neal Norwitz65851662006-01-16 04:31:40 +000042# ifdef HAVE_ASM_TYPES_H
43# include <asm/types.h>
44# endif
Martin v. Löwis11017b12006-01-14 18:12:57 +000045# include <linux/netlink.h>
46#else
47# undef AF_NETLINK
48#endif
49
Martin v. Löwis12af0482004-01-31 12:34:17 +000050#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>
Thomas Wouterscf297e42007-02-23 15:07:44 +000055#include <bluetooth/hci.h>
Martin v. Löwis12af0482004-01-31 12:34:17 +000056#endif
57
Hye-Shik Chang96c446582004-02-02 08:48:45 +000058#ifdef HAVE_BLUETOOTH_H
59#include <bluetooth.h>
60#endif
61
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000062#ifdef HAVE_NETPACKET_PACKET_H
63# include <sys/ioctl.h>
64# include <net/if.h>
65# include <netpacket/packet.h>
66#endif
67
Christian Heimes043d6f62008-01-07 17:19:16 +000068#ifdef HAVE_LINUX_TIPC_H
69# include <linux/tipc.h>
70#endif
71
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000072#ifndef Py__SOCKET_H
73#define Py__SOCKET_H
74#ifdef __cplusplus
75extern "C" {
76#endif
77
78/* Python module and C API name */
79#define PySocket_MODULE_NAME "_socket"
80#define PySocket_CAPI_NAME "CAPI"
81
82/* Abstract the socket file descriptor type */
83#ifdef MS_WINDOWS
84typedef SOCKET SOCKET_T;
85# ifdef MS_WIN64
86# define SIZEOF_SOCKET_T 8
87# else
88# define SIZEOF_SOCKET_T 4
89# endif
90#else
91typedef int SOCKET_T;
92# define SIZEOF_SOCKET_T SIZEOF_INT
93#endif
94
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +000095/* Socket address */
96typedef union sock_addr {
97 struct sockaddr_in in;
98#ifdef AF_UNIX
99 struct sockaddr_un un;
100#endif
Martin v. Löwis11017b12006-01-14 18:12:57 +0000101#ifdef AF_NETLINK
102 struct sockaddr_nl nl;
103#endif
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +0000104#ifdef ENABLE_IPV6
105 struct sockaddr_in6 in6;
106 struct sockaddr_storage storage;
107#endif
108#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
109 struct sockaddr_l2 bt_l2;
110 struct sockaddr_rc bt_rc;
111 struct sockaddr_sco bt_sco;
Thomas Wouterscf297e42007-02-23 15:07:44 +0000112 struct sockaddr_hci bt_hci;
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +0000113#endif
114#ifdef HAVE_NETPACKET_PACKET_H
115 struct sockaddr_ll ll;
116#endif
117} sock_addr_t;
118
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000119/* The object holding a socket. It holds some extra information,
120 like the address family, which is used to decode socket address
121 arguments properly. */
122
123typedef struct {
124 PyObject_HEAD
125 SOCKET_T sock_fd; /* Socket file descriptor */
126 int sock_family; /* Address family, e.g., AF_INET */
127 int sock_type; /* Socket type, e.g., SOCK_STREAM */
128 int sock_proto; /* Protocol type, usually 0 */
Tim Peters6f5505a2002-02-17 03:58:51 +0000129 PyObject *(*errorhandler)(void); /* Error handler; checks
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000130 errno, returns NULL and
131 sets a Python exception */
Guido van Rossum11ba0942002-06-13 15:07:44 +0000132 double sock_timeout; /* Operation timeout in seconds;
133 0.0 means non-blocking */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000134} PySocketSockObject;
135
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000136/* --- C API ----------------------------------------------------*/
137
Marc-André Lemburg666e70d2002-02-25 14:45:40 +0000138/* Short explanation of what this C API export mechanism does
139 and how it works:
140
141 The _ssl module needs access to the type object defined in
142 the _socket module. Since cross-DLL linking introduces a lot of
143 problems on many platforms, the "trick" is to wrap the
144 C API of a module in a struct which then gets exported to
145 other modules via a PyCObject.
146
147 The code in socketmodule.c defines this struct (which currently
148 only contains the type object reference, but could very
149 well also include other C APIs needed by other modules)
150 and exports it as PyCObject via the module dictionary
151 under the name "CAPI".
152
153 Other modules can now include the socketmodule.h file
154 which defines the needed C APIs to import and set up
155 a static copy of this struct in the importing module.
156
157 After initialization, the importing module can then
158 access the C APIs from the _socket module by simply
159 referring to the static struct, e.g.
160
161 Load _socket module and its C API; this sets up the global
162 PySocketModule:
163
164 if (PySocketModule_ImportModuleAndAPI())
165 return;
166
167
168 Now use the C API as if it were defined in the using
169 module:
170
171 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
172
173 PySocketModule.Sock_Type,
174
175 (PyObject*)&Sock,
176 &key_file, &cert_file))
177 return NULL;
178
179 Support could easily be extended to export more C APIs/symbols
180 this way. Currently, only the type object is exported,
181 other candidates would be socket constructors and socket
182 access functions.
183
184*/
185
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000186/* C API for usage by other Python modules */
187typedef struct {
Tim Peters6f5505a2002-02-17 03:58:51 +0000188 PyTypeObject *Sock_Type;
Brett Cannon06c34792004-03-23 23:16:54 +0000189 PyObject *error;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000190} PySocketModule_APIObject;
Tim Peters6f5505a2002-02-17 03:58:51 +0000191
192/* XXX The net effect of the following appears to be to define a function
193 XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't
Marc-André Lemburg666e70d2002-02-25 14:45:40 +0000194 XXX defined there directly.
195
196 >>> It's defined here because other modules might also want to use
197 >>> the C API.
198
199*/
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000200#ifndef PySocket_BUILDING_SOCKET
201
202/* --- C API ----------------------------------------------------*/
203
204/* Interfacestructure to C API for other modules.
Guido van Rossumbe8db072002-06-07 02:27:50 +0000205 Call PySocketModule_ImportModuleAndAPI() to initialize this
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000206 structure. After that usage is simple:
207
208 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
209 &PySocketModule.Sock_Type, (PyObject*)&Sock,
210 &key_file, &cert_file))
211 return NULL;
212 ...
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000213*/
214
Tim Peters6f5505a2002-02-17 03:58:51 +0000215static
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000216PySocketModule_APIObject PySocketModule;
217
218/* You *must* call this before using any of the functions in
219 PySocketModule and check its outcome; otherwise all accesses will
220 result in a segfault. Returns 0 on success. */
221
222#ifndef DPRINTF
223# define DPRINTF if (0) printf
224#endif
225
226static
227int PySocketModule_ImportModuleAndAPI(void)
228{
Tim Peters6f5505a2002-02-17 03:58:51 +0000229 PyObject *mod = 0, *v = 0;
230 char *apimodule = PySocket_MODULE_NAME;
231 char *apiname = PySocket_CAPI_NAME;
232 void *api;
233
234 DPRINTF("Importing the %s C API...\n", apimodule);
Christian Heimes072c0f12008-01-03 23:01:04 +0000235 mod = PyImport_ImportModuleNoBlock(apimodule);
Tim Peters6f5505a2002-02-17 03:58:51 +0000236 if (mod == NULL)
237 goto onError;
238 DPRINTF(" %s package found\n", apimodule);
239 v = PyObject_GetAttrString(mod, apiname);
240 if (v == NULL)
241 goto onError;
242 Py_DECREF(mod);
243 DPRINTF(" API object %s found\n", apiname);
244 api = PyCObject_AsVoidPtr(v);
245 if (api == NULL)
246 goto onError;
247 Py_DECREF(v);
248 memcpy(&PySocketModule, api, sizeof(PySocketModule));
249 DPRINTF(" API object loaded and initialized.\n");
250 return 0;
251
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000252 onError:
Tim Peters6f5505a2002-02-17 03:58:51 +0000253 DPRINTF(" not found.\n");
254 Py_XDECREF(mod);
255 Py_XDECREF(v);
256 return -1;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000257}
258
Tim Peters6f5505a2002-02-17 03:58:51 +0000259#endif /* !PySocket_BUILDING_SOCKET */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000260
261#ifdef __cplusplus
262}
263#endif
264#endif /* !Py__SOCKET_H */