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