1 /**
2  * D header file for POSIX.
3  *
4  * Copyright: Public Domain
5  * License:   Public Domain
6  * Authors:   Sean Kelly
7  * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
8  */
9 module tango.stdc.posix.sys.socket;
10 
11 private import tango.stdc.posix.config;
12 public import tango.stdc.posix.sys.types; // for ssize_t, size_t
13 public import tango.stdc.posix.sys.uio;   // for iovec
14 public import tango.sys.consts.socket;
15 extern (C):
16 
17 //
18 // Required
19 //
20 /*
21 socklen_t
22 sa_family_t
23 
24 struct sockaddr
25 {
26     sa_family_t sa_family;
27     char        sa_data[];
28 }
29 
30 struct sockaddr_storage
31 {
32     sa_family_t ss_family;
33 }
34 
35 struct msghdr
36 {
37     void*         msg_name;
38     socklen_t     msg_namelen;
39     struct iovec* msg_iov;
40     int           msg_iovlen;
41     void*         msg_control;
42     socklen_t     msg_controllen;
43     int           msg_flags;
44 }
45 
46 struct iovec {} // from tango.stdc.posix.sys.uio
47 
48 struct cmsghdr
49 {
50     socklen_t cmsg_len;
51     int       cmsg_level;
52     int       cmsg_type;
53 }
54 
55 SCM_RIGHTS
56 
57 CMSG_DATA(cmsg)
58 CMSG_NXTHDR(mhdr,cmsg)
59 CMSG_FIRSTHDR(mhdr)
60 
61 struct linger
62 {
63     int l_onoff;
64     int l_linger;
65 }
66 
67 SOCK_DGRAM
68 SOCK_SEQPACKET
69 SOCK_STREAM
70 
71 SOL_SOCKET
72 
73 SO_ACCEPTCONN
74 SO_BROADCAST
75 SO_DEBUG
76 SO_DONTROUTE
77 SO_ERROR
78 SO_KEEPALIVE
79 SO_LINGER
80 SO_OOBINLINE
81 SO_RCVBUF
82 SO_RCVLOWAT
83 SO_RCVTIMEO
84 SO_REUSEADDR
85 SO_SNDBUF
86 SO_SNDLOWAT
87 SO_SNDTIMEO
88 SO_TYPE
89 
90 SOMAXCONN
91 
92 MSG_CTRUNC
93 MSG_DONTROUTE
94 MSG_EOR
95 MSG_OOB
96 MSG_PEEK
97 MSG_TRUNC
98 MSG_WAITALL
99 
100 AF_INET
101 AF_UNIX
102 AF_UNSPEC
103 
104 SHUT_RD
105 SHUT_RDWR
106 SHUT_WR
107 
108 int     accept(int, sockaddr*, socklen_t*);
109 int     bind(int, in sockaddr*, socklen_t);
110 int     connect(int, in sockaddr*, socklen_t);
111 int     getpeername(int, sockaddr*, socklen_t*);
112 int     getsockname(int, sockaddr*, socklen_t*);
113 int     getsockopt(int, int, int, void*, socklen_t*);
114 int     listen(int, int);
115 ssize_t recv(int, void*, size_t, int);
116 ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*);
117 ssize_t recvmsg(int, msghdr*, int);
118 ssize_t send(int, in void*, size_t, int);
119 ssize_t sendmsg(int, in msghdr*, int);
120 ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t);
121 int     setsockopt(int, int, int, in void*, socklen_t);
122 int     shutdown(int, int);
123 int     socket(int, int, int);
124 int     sockatmark(int);
125 int     socketpair(int, int, int, int[2]);
126 */
127 
128 version( linux )
129 {
130     alias uint   socklen_t;
131     alias ushort sa_family_t;
132 
133     struct sockaddr
134     {
135         sa_family_t sa_family;
136         byte[14]    sa_data;
137     }
138 
139     private enum : size_t
140     {
141         _SS_SIZE    = 128,
142         _SS_PADSIZE = _SS_SIZE - (c_ulong.sizeof * 2)
143     }
144 
145     struct sockaddr_storage
146     {
147         sa_family_t ss_family;
148         c_ulong     __ss_align;
149         byte[_SS_PADSIZE] __ss_padding;
150     }
151 
152     struct msghdr
153     {
154         void*     msg_name;
155         socklen_t msg_namelen;
156         iovec*    msg_iov;
157         size_t    msg_iovlen;
158         void*     msg_control;
159         size_t    msg_controllen;
160         int       msg_flags;
161     }
162 
163     struct cmsghdr
164     {
165         size_t cmsg_len;
166         int    cmsg_level;
167         int    cmsg_type;
168         static if( false /* (!is( __STRICT_ANSI__ ) && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L */ )
169         {
170             ubyte[1] __cmsg_data;
171         }
172     }
173 
174     static if( false /* (!is( __STRICT_ANSI__ ) && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L */ )
175     {
176         extern (D) ubyte[1] CMSG_DATA( cmsghdr* cmsg ) { return cmsg.__cmsg_data; }
177     }
178     else
179     {
180         extern (D) ubyte*   CMSG_DATA( cmsghdr* cmsg ) { return cast(ubyte*)( cmsg + 1 ); }
181     }
182 
183     private cmsghdr* __cmsg_nxthdr(msghdr*, cmsghdr*);
184     alias            __cmsg_nxthdr CMSG_NXTHDR;
185 
186     extern (D) size_t CMSG_FIRSTHDR( msghdr* mhdr )
187     {
188         return ( mhdr.msg_controllen >= cmsghdr.sizeof
189                              ? cast(size_t) mhdr.msg_control
190                              : cast(size_t) 0 );
191     }
192 
193     struct linger
194     {
195         int l_onoff;
196         int l_linger;
197     }
198 
199     int     accept(int, sockaddr*, socklen_t*);
200     int     bind(int, in sockaddr*, socklen_t);
201     int     connect(int, in sockaddr*, socklen_t);
202     int     getpeername(int, sockaddr*, socklen_t*);
203     int     getsockname(int, sockaddr*, socklen_t*);
204     int     getsockopt(int, int, int, void*, socklen_t*);
205     int     listen(int, int);
206     ssize_t recv(int, void*, size_t, int);
207     ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*);
208     ssize_t recvmsg(int, msghdr*, int);
209     ssize_t send(int, in void*, size_t, int);
210     ssize_t sendmsg(int, in msghdr*, int);
211     ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t);
212     int     setsockopt(int, int, int, in void*, socklen_t);
213     int     shutdown(int, int);
214     int     socket(int, int, int);
215     int     sockatmark(int);
216     int     socketpair(int, int, int, int[2]);
217 }
218 else version(OSX)
219 {
220     alias uint   socklen_t;
221     alias ubyte  sa_family_t;
222 
223     struct sockaddr
224     {
225         ubyte       sa_len;
226         sa_family_t sa_family;
227         byte[14]    sa_data;
228     }
229 
230     private enum : size_t
231     {
232         _SS_PAD1    = long.sizeof - ubyte.sizeof - sa_family_t.sizeof,
233         _SS_PAD2    = 128 - ubyte.sizeof - sa_family_t.sizeof - _SS_PAD1 - long.sizeof
234     }
235 
236     struct sockaddr_storage
237     {
238          ubyte          ss_len;
239          sa_family_t    ss_family;
240          byte[_SS_PAD1] __ss_pad1;
241          long           __ss_align;
242          byte[_SS_PAD2] __ss_pad2;
243     }
244 
245     struct msghdr
246     {
247         void*     msg_name;
248         socklen_t msg_namelen;
249         iovec*    msg_iov;
250         int       msg_iovlen;
251         void*     msg_control;
252         socklen_t msg_controllen;
253         int       msg_flags;
254     }
255 
256     struct cmsghdr
257     {
258          socklen_t cmsg_len;
259          int       cmsg_level;
260          int       cmsg_type;
261     }
262 
263     /+
264     CMSG_DATA(cmsg)     ((unsigned char *)(cmsg) + \
265                          ALIGN(sizeof(struct cmsghdr)))
266     CMSG_NXTHDR(mhdr, cmsg) \
267                         (((unsigned char *)(cmsg) + ALIGN((cmsg)->cmsg_len) + \
268                          ALIGN(sizeof(struct cmsghdr)) > \
269                          (unsigned char *)(mhdr)->msg_control +(mhdr)->msg_controllen) ? \
270                          (struct cmsghdr *)0 /* NULL */ : \
271                          (struct cmsghdr *)((unsigned char *)(cmsg) + ALIGN((cmsg)->cmsg_len)))
272     CMSG_FIRSTHDR(mhdr) ((struct cmsghdr *)(mhdr)->msg_control)
273     +/
274 
275     struct linger
276     {
277         int l_onoff;
278         int l_linger;
279     }
280 
281     int     accept(int, sockaddr*, socklen_t*);
282     int     bind(int, in sockaddr*, socklen_t);
283     int     connect(int, in sockaddr*, socklen_t);
284     int     getpeername(int, sockaddr*, socklen_t*);
285     int     getsockname(int, sockaddr*, socklen_t*);
286     int     getsockopt(int, int, int, void*, socklen_t*);
287     int     listen(int, int);
288     ssize_t recv(int, void*, size_t, int);
289     ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*);
290     ssize_t recvmsg(int, msghdr*, int);
291     ssize_t send(int, in void*, size_t, int);
292     ssize_t sendmsg(int, in msghdr*, int);
293     ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t);
294     int     setsockopt(int, int, int, in void*, socklen_t);
295     int     shutdown(int, int);
296     int     socket(int, int, int);
297     int     sockatmark(int);
298     int     socketpair(int, int, int, int[2]);
299 }
300 else version( FreeBSD )
301 {
302     alias uint   socklen_t;
303     alias ubyte  sa_family_t;
304 
305     struct sockaddr
306     {
307         ubyte       sa_len;
308         sa_family_t sa_family;
309         byte[14]    sa_data;
310     }
311 
312     private
313     {
314         const _SS_ALIGNSIZE = long.sizeof;
315         const uint _SS_MAXSIZE = 128;
316         const _SS_PAD1SIZE = _SS_ALIGNSIZE - ubyte.sizeof - sa_family_t.sizeof;
317         const _SS_PAD2SIZE = _SS_MAXSIZE - ubyte.sizeof - sa_family_t.sizeof - _SS_PAD1SIZE - _SS_ALIGNSIZE;
318     }
319 
320     struct sockaddr_storage
321     {
322          ubyte          ss_len;
323          sa_family_t    ss_family;
324          byte[_SS_PAD1SIZE] __ss_pad1;
325          long           __ss_align;
326          byte[_SS_PAD2SIZE] __ss_pad2;
327     }
328 
329     struct msghdr
330     {
331         void*     msg_name;
332         socklen_t msg_namelen;
333         iovec*    msg_iov;
334         int       msg_iovlen;
335         void*     msg_control;
336         socklen_t msg_controllen;
337         int       msg_flags;
338     }
339 
340     struct cmsghdr
341     {
342          socklen_t cmsg_len;
343          int       cmsg_level;
344          int       cmsg_type;
345     }
346 
347     /+
348     CMSG_DATA(cmsg)     ((unsigned char *)(cmsg) + \
349                          ALIGN(sizeof(struct cmsghdr)))
350     CMSG_NXTHDR(mhdr, cmsg) \
351                         (((unsigned char *)(cmsg) + ALIGN((cmsg)->cmsg_len) + \
352                          ALIGN(sizeof(struct cmsghdr)) > \
353                          (unsigned char *)(mhdr)->msg_control +(mhdr)->msg_controllen) ? \
354                          (struct cmsghdr *)0 /* NULL */ : \
355                          (struct cmsghdr *)((unsigned char *)(cmsg) + ALIGN((cmsg)->cmsg_len)))
356     CMSG_FIRSTHDR(mhdr) ((struct cmsghdr *)(mhdr)->msg_control)
357     +/
358 
359     struct linger
360     {
361         int l_onoff;
362         int l_linger;
363     }
364 
365     int     accept(int, sockaddr*, socklen_t*);
366     int     bind(int, in sockaddr*, socklen_t);
367     int     connect(int, in sockaddr*, socklen_t);
368     int     getpeername(int, sockaddr*, socklen_t*);
369     int     getsockname(int, sockaddr*, socklen_t*);
370     int     getsockopt(int, int, int, void*, socklen_t*);
371     int     listen(int, int);
372     ssize_t recv(int, void*, size_t, int);
373     ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*);
374     ssize_t recvmsg(int, msghdr*, int);
375     ssize_t send(int, in void*, size_t, int);
376     ssize_t sendmsg(int, in msghdr*, int);
377     ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t);
378     int     setsockopt(int, int, int, in void*, socklen_t);
379     int     shutdown(int, int);
380     int     socket(int, int, int);
381     int     sockatmark(int);
382     int     socketpair(int, int, int, int[2]);
383 }
384 else version( solaris )
385 {
386     alias uint   socklen_t;
387     alias ushort sa_family_t;
388 
389     struct sockaddr
390     {
391         sa_family_t sa_family;
392         char[14]    sa_data;
393     }
394 
395     private
396     {
397         alias double sockaddr_maxalign_t;
398         const _SS_ALIGNSIZE = sockaddr_maxalign_t.sizeof;
399         const _SS_MAXSIZE   = 256;
400         const _SS_PAD1SIZE  = _SS_ALIGNSIZE - sa_family_t.sizeof;
401         const _SS_PAD2SIZE  = _SS_MAXSIZE - (sa_family_t.sizeof + _SS_PAD1SIZE + _SS_ALIGNSIZE);
402     }
403 
404     struct sockaddr_storage
405     {
406         sa_family_t ss_family;  /* Address family */
407         /* Following fields are implementation specific */
408         char[_SS_PAD1SIZE]        _ss_pad1;
409         sockaddr_maxalign_t _ss_align;
410         char[_SS_PAD2SIZE]        _ss_pad2;
411     }
412     
413     struct msghdr
414     {
415         void*         msg_name;
416         socklen_t     msg_namelen;
417         iovec*        msg_iov;
418         int           msg_iovlen;
419         void*         msg_control;
420         socklen_t     msg_controllen;
421         int           msg_flags;
422     }
423 
424     struct iovec {} // from tango.stdc.posix.sys.uio
425 
426     struct cmsghdr
427     {
428         socklen_t cmsg_len;
429         int       cmsg_level;
430         int       cmsg_type;
431     }
432     
433     private
434     {
435         const _CMSG_DATA_ALIGNMENT = int.sizeof;
436         version (X86)           const _CMSG_HDR_ALIGNMENT = 4;
437         else version(X86_64)    const _CMSG_HDR_ALIGNMENT = 4;
438         else /* SPARC */        const _CMSG_HDR_ALIGNMENT = 8;
439         
440         extern (D)
441         {
442             private ubyte* _CMSG_DATA_ALIGN(cmsghdr* x) { 
443                 return cast(ubyte*)((cast(size_t)x + _CMSG_DATA_ALIGNMENT - 1) & ~(_CMSG_DATA_ALIGNMENT - 1));
444             }
445             private size_t _CMSG_HDR_ALIGN(cmsghdr* x) { 
446                 return (cast(size_t)x + _CMSG_HDR_ALIGNMENT - 1) & ~(_CMSG_HDR_ALIGNMENT - 1);
447             }
448         }
449     }
450     
451     extern (D) ubyte*   CMSG_DATA( cmsghdr* cmsg ) { return cast(ubyte*)_CMSG_DATA_ALIGN( cmsg + 1 ); }
452 
453     extern (D) cmsghdr* CMSG_FIRSTHDR( msghdr* mhdr )
454     {
455         return mhdr.msg_controllen >= cmsghdr.sizeof
456             ? cast(cmsghdr*) mhdr.msg_control
457             : null;
458     }
459 
460     extern (D) cmsghdr* CMSG_NXTHDR( msghdr* m, cmsghdr* c )
461     {
462         /* Hurrah for unreadable C macros! */
463         
464         if(c is null) return CMSG_FIRSTHDR(m);
465         
466         size_t aligned_cmsg = _CMSG_HDR_ALIGN(c);
467         return
468             (aligned_cmsg + c.cmsg_len + cmsghdr.sizeof) > (cast(size_t)m.msg_control + m.msg_controllen)
469             ? null
470             : cast(cmsghdr*)(aligned_cmsg + c.cmsg_len);
471     }
472     
473     struct linger
474     {
475         int l_onoff;
476         int l_linger;
477     }
478 
479 
480     int     accept(int, sockaddr*, socklen_t*);
481     int     bind(int, in sockaddr*, socklen_t);
482     int     connect(int, in sockaddr*, socklen_t);
483     int     getpeername(int, sockaddr*, socklen_t*);
484     int     getsockname(int, sockaddr*, socklen_t*);
485     int     getsockopt(int, int, int, void*, socklen_t*);
486     int     listen(int, int);
487     ssize_t recv(int, void*, size_t, int);
488     ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*);
489     ssize_t recvmsg(int, msghdr*, int);
490     ssize_t send(int, in void*, size_t, int);
491     ssize_t sendmsg(int, in msghdr*, int);
492     ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t);
493     int     setsockopt(int, int, int, in void*, socklen_t);
494     int     shutdown(int, int);
495     int     socket(int, int, int);
496     int     sockatmark(int);
497     int     socketpair(int, int, int, int[2]);
498 }