1 /**
2  * D header file for POSIX.
3  *
4  * Copyright: Copyright Sean Kelly 2005 - 2009.
5  * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6  * Authors:   Sean Kelly, Alex Rønne Petersen
7  * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
8  */
9 
10 /*          Copyright Sean Kelly 2005 - 2009.
11  * Distributed under the Boost Software License, Version 1.0.
12  *    (See accompanying file LICENSE or copy at
13  *          http://www.boost.org/LICENSE_1_0.txt)
14  */
15 module core.sys.posix.sys.socket;
16 
17 import core.sys.posix.config;
18 public import core.sys.posix.sys.types; // for ssize_t
19 public import core.sys.posix.sys.uio;   // for iovec
20 
21 version (OSX)
22     version = Darwin;
23 else version (iOS)
24     version = Darwin;
25 else version (TVOS)
26     version = Darwin;
27 else version (WatchOS)
28     version = Darwin;
29 
30 version (ARM)     version = ARM_Any;
31 version (AArch64) version = ARM_Any;
32 version (HPPA)    version = HPPA_Any;
33 version (MIPS32)  version = MIPS_Any;
34 version (MIPS64)  version = MIPS_Any;
35 version (PPC)     version = PPC_Any;
36 version (PPC64)   version = PPC_Any;
37 version (RISCV32) version = RISCV_Any;
38 version (RISCV64) version = RISCV_Any;
39 version (S390)    version = IBMZ_Any;
40 version (SPARC)   version = SPARC_Any;
41 version (SPARC64) version = SPARC_Any;
42 version (SystemZ) version = IBMZ_Any;
43 version (X86)     version = X86_Any;
44 version (X86_64)  version = X86_Any;
45 
46 version (Posix):
47 extern (C) nothrow @nogc:
48 
49 //
50 // Required
51 //
52 /*
53 socklen_t
54 sa_family_t
55 
56 struct sockaddr
57 {
58     sa_family_t sa_family;
59     char        sa_data[];
60 }
61 
62 struct sockaddr_storage
63 {
64     sa_family_t ss_family;
65 }
66 
67 struct msghdr
68 {
69     void*         msg_name;
70     socklen_t     msg_namelen;
71     struct iovec* msg_iov;
72     int           msg_iovlen;
73     void*         msg_control;
74     socklen_t     msg_controllen;
75     int           msg_flags;
76 }
77 
78 struct iovec {} // from core.sys.posix.sys.uio
79 
80 struct cmsghdr
81 {
82     socklen_t cmsg_len;
83     int       cmsg_level;
84     int       cmsg_type;
85 }
86 
87 SCM_RIGHTS
88 
89 CMSG_DATA(cmsg)
90 CMSG_NXTHDR(mhdr,cmsg)
91 CMSG_FIRSTHDR(mhdr)
92 
93 struct linger
94 {
95     int l_onoff;
96     int l_linger;
97 }
98 
99 SOCK_DGRAM
100 SOCK_SEQPACKET
101 SOCK_STREAM
102 
103 SOL_SOCKET
104 
105 SO_ACCEPTCONN
106 SO_BROADCAST
107 SO_DEBUG
108 SO_DONTROUTE
109 SO_ERROR
110 SO_KEEPALIVE
111 SO_LINGER
112 SO_OOBINLINE
113 SO_RCVBUF
114 SO_RCVLOWAT
115 SO_RCVTIMEO
116 SO_REUSEADDR
117 SO_SNDBUF
118 SO_SNDLOWAT
119 SO_SNDTIMEO
120 SO_TYPE
121 
122 SOMAXCONN
123 
124 MSG_CTRUNC
125 MSG_DONTROUTE
126 MSG_EOR
127 MSG_OOB
128 MSG_PEEK
129 MSG_TRUNC
130 MSG_WAITALL
131 
132 AF_INET
133 AF_UNIX
134 AF_UNSPEC
135 
136 SHUT_RD
137 SHUT_RDWR
138 SHUT_WR
139 */
140 
141 version (linux)
142 {
143     alias uint   socklen_t;
144     alias ushort sa_family_t;
145 
146     struct sockaddr
147     {
148         sa_family_t sa_family;
149         byte[14]    sa_data;
150     }
151 
152     private enum : size_t
153     {
154         _SS_SIZE    = 128,
155         _SS_PADSIZE = _SS_SIZE - c_ulong.sizeof - sa_family_t.sizeof
156     }
157 
158     struct sockaddr_storage
159     {
160         sa_family_t ss_family;
161         byte[_SS_PADSIZE] __ss_padding;
162         c_ulong     __ss_align;
163     }
164 
165     struct msghdr
166     {
167         void*     msg_name;
168         socklen_t msg_namelen;
169         iovec*    msg_iov;
170         size_t    msg_iovlen;
171         void*     msg_control;
172         size_t    msg_controllen;
173         int       msg_flags;
174     }
175 
176     struct cmsghdr
177     {
178         size_t cmsg_len;
179         int    cmsg_level;
180         int    cmsg_type;
181     }
182 
183     enum : uint
184     {
185         SCM_RIGHTS = 0x01
186     }
187 
188     extern (D) inout(ubyte)*   CMSG_DATA( return scope inout(cmsghdr)* cmsg ) pure nothrow @nogc { return cast(ubyte*)( cmsg + 1 ); }
189 
190     version (CRuntime_Musl)
191     {
192         extern (D)
193         {
194             private size_t __CMSG_LEN(inout(cmsghdr)* cmsg) pure nothrow @nogc
195             {
196                 return (cmsg.cmsg_len + size_t.sizeof -1) & cast(size_t)(~(size_t.sizeof - 1));
197             }
198 
199             private inout(cmsghdr)* __CMSG_NEXT(inout(cmsghdr)* cmsg) pure nothrow @nogc
200             {
201                 return cmsg + __CMSG_LEN(cmsg);
202             }
203 
204             private inout(msghdr)* __MHDR_END(inout(msghdr)* mhdr) pure nothrow @nogc
205             {
206                 return cast(inout(msghdr)*)(mhdr.msg_control + mhdr.msg_controllen);
207             }
208 
209             inout(cmsghdr)* CMSG_NXTHDR(inout(msghdr)* msg, inout(cmsghdr)* cmsg) pure nothrow @nogc
210             {
211                 return cmsg.cmsg_len < cmsghdr.sizeof ||
212                     __CMSG_LEN(cmsg) + cmsghdr.sizeof >= __MHDR_END(msg) - cast(inout(msghdr)*)(cmsg)
213                         ? cast(inout(cmsghdr)*) null : cast(inout(cmsghdr)*) __CMSG_NEXT(cmsg);
214             }
215         }
216     }
217     else
218     {
219         private inout(cmsghdr)* __cmsg_nxthdr(inout(msghdr)*, inout(cmsghdr)*) pure nothrow @nogc;
220         extern (D)  inout(cmsghdr)* CMSG_NXTHDR(inout(msghdr)* msg, inout(cmsghdr)* cmsg) pure nothrow @nogc
221         {
222             return __cmsg_nxthdr(msg, cmsg);
223         }
224     }
225 
226     extern (D) inout(cmsghdr)* CMSG_FIRSTHDR( inout(msghdr)* mhdr ) pure nothrow @nogc
227     {
228         return ( cast(size_t)mhdr.msg_controllen >= cmsghdr.sizeof
229                              ? cast(inout(cmsghdr)*) mhdr.msg_control
230                              : cast(inout(cmsghdr)*) null );
231     }
232 
233     extern (D)
234     {
235         size_t CMSG_ALIGN( size_t len ) pure nothrow @nogc
236         {
237             return (len + size_t.sizeof - 1) & cast(size_t) (~(size_t.sizeof - 1));
238         }
239 
240         size_t CMSG_LEN( size_t len ) pure nothrow @nogc
241         {
242             return CMSG_ALIGN(cmsghdr.sizeof) + len;
243         }
244     }
245 
246     extern (D) size_t CMSG_SPACE(size_t len) pure nothrow @nogc
247     {
248         return CMSG_ALIGN(len) + CMSG_ALIGN(cmsghdr.sizeof);
249     }
250 
251     struct linger
252     {
253         int l_onoff;
254         int l_linger;
255     }
256 
257     version (X86_Any)
258     {
259         enum
260         {
261             SOCK_DGRAM      = 2,
262             SOCK_SEQPACKET  = 5,
263             SOCK_STREAM     = 1
264         }
265 
266         enum
267         {
268             SOL_SOCKET      = 1
269         }
270 
271         enum
272         {
273             SO_ACCEPTCONN   = 30,
274             SO_BROADCAST    = 6,
275             SO_DEBUG        = 1,
276             SO_DONTROUTE    = 5,
277             SO_ERROR        = 4,
278             SO_KEEPALIVE    = 9,
279             SO_LINGER       = 13,
280             SO_OOBINLINE    = 10,
281             SO_RCVBUF       = 8,
282             SO_RCVLOWAT     = 18,
283             SO_RCVTIMEO     = 20,
284             SO_REUSEADDR    = 2,
285             SO_REUSEPORT    = 15,
286             SO_SNDBUF       = 7,
287             SO_SNDLOWAT     = 19,
288             SO_SNDTIMEO     = 21,
289             SO_TYPE         = 3
290         }
291     }
292     else version (HPPA_Any)
293     {
294         enum
295         {
296             SOCK_DGRAM      = 2,
297             SOCK_SEQPACKET  = 5,
298             SOCK_STREAM     = 1,
299         }
300 
301         enum
302         {
303             SOL_SOCKET      = 0xffff
304         }
305 
306         enum
307         {
308             SO_ACCEPTCONN   = 0x401c,
309             SO_BROADCAST    = 0x0020,
310             SO_DEBUG        = 0x0001,
311             SO_DONTROUTE    = 0x0010,
312             SO_ERROR        = 0x1007,
313             SO_KEEPALIVE    = 0x0008,
314             SO_LINGER       = 0x0080,
315             SO_OOBINLINE    = 0x0100,
316             SO_RCVBUF       = 0x1002,
317             SO_RCVLOWAT     = 0x1004,
318             SO_RCVTIMEO     = 0x1006,
319             SO_REUSEADDR    = 0x0004,
320             SO_SNDBUF       = 0x1001,
321             SO_SNDLOWAT     = 0x1003,
322             SO_SNDTIMEO     = 0x1005,
323             SO_TYPE         = 0x1008,
324         }
325     }
326     else version (MIPS_Any)
327     {
328         enum
329         {
330             SOCK_DGRAM      = 1,
331             SOCK_SEQPACKET  = 5,
332             SOCK_STREAM     = 2,
333         }
334 
335         enum
336         {
337             SOL_SOCKET      = 0xffff
338         }
339 
340         enum
341         {
342             SO_ACCEPTCONN   = 0x1009,
343             SO_BROADCAST    = 0x0020,
344             SO_DEBUG        = 0x0001,
345             SO_DONTROUTE    = 0x0010,
346             SO_ERROR        = 0x1007,
347             SO_KEEPALIVE    = 0x0008,
348             SO_LINGER       = 0x0080,
349             SO_OOBINLINE    = 0x0100,
350             SO_RCVBUF       = 0x1002,
351             SO_RCVLOWAT     = 0x1004,
352             SO_RCVTIMEO     = 0x1006,
353             SO_REUSEADDR    = 0x0004,
354             SO_SNDBUF       = 0x1001,
355             SO_SNDLOWAT     = 0x1003,
356             SO_SNDTIMEO     = 0x1005,
357             SO_TYPE         = 0x1008,
358         }
359     }
360     else version (PPC_Any)
361     {
362         enum
363         {
364             SOCK_DGRAM      = 2,
365             SOCK_SEQPACKET  = 5,
366             SOCK_STREAM     = 1
367         }
368 
369         enum
370         {
371             SOL_SOCKET      = 1
372         }
373 
374         enum
375         {
376             SO_ACCEPTCONN   = 30,
377             SO_BROADCAST    = 6,
378             SO_DEBUG        = 1,
379             SO_DONTROUTE    = 5,
380             SO_ERROR        = 4,
381             SO_KEEPALIVE    = 9,
382             SO_LINGER       = 13,
383             SO_OOBINLINE    = 10,
384             SO_RCVBUF       = 8,
385             SO_RCVLOWAT     = 16,
386             SO_RCVTIMEO     = 18,
387             SO_REUSEADDR    = 2,
388             SO_SNDBUF       = 7,
389             SO_SNDLOWAT     = 17,
390             SO_SNDTIMEO     = 19,
391             SO_TYPE         = 3
392         }
393     }
394     else version (ARM_Any)
395     {
396         enum
397         {
398             SOCK_DGRAM      = 2,
399             SOCK_SEQPACKET  = 5,
400             SOCK_STREAM     = 1
401         }
402 
403         enum
404         {
405             SOL_SOCKET      = 1
406         }
407 
408         enum
409         {
410             SO_ACCEPTCONN   = 30,
411             SO_BROADCAST    = 6,
412             SO_DEBUG        = 1,
413             SO_DONTROUTE    = 5,
414             SO_ERROR        = 4,
415             SO_KEEPALIVE    = 9,
416             SO_LINGER       = 13,
417             SO_OOBINLINE    = 10,
418             SO_RCVBUF       = 8,
419             SO_RCVLOWAT     = 18,
420             SO_RCVTIMEO     = 20,
421             SO_REUSEADDR    = 2,
422             SO_REUSEPORT    = 15,
423             SO_SNDBUF       = 7,
424             SO_SNDLOWAT     = 19,
425             SO_SNDTIMEO     = 21,
426             SO_TYPE         = 3
427         }
428     }
429     else version (RISCV_Any)
430     {
431         enum
432         {
433             SOCK_DGRAM      = 2,
434             SOCK_SEQPACKET  = 5,
435             SOCK_STREAM     = 1
436         }
437 
438         enum
439         {
440             SOL_SOCKET      = 1
441         }
442 
443         enum
444         {
445             SO_ACCEPTCONN   = 30,
446             SO_BROADCAST    = 6,
447             SO_DEBUG        = 1,
448             SO_DONTROUTE    = 5,
449             SO_ERROR        = 4,
450             SO_KEEPALIVE    = 9,
451             SO_LINGER       = 13,
452             SO_OOBINLINE    = 10,
453             SO_RCVBUF       = 8,
454             SO_RCVLOWAT     = 18,
455             SO_RCVTIMEO     = 20,
456             SO_REUSEADDR    = 2,
457             SO_SNDBUF       = 7,
458             SO_SNDLOWAT     = 19,
459             SO_SNDTIMEO     = 21,
460             SO_TYPE         = 3
461         }
462     }
463     else version (SPARC_Any)
464     {
465         enum
466         {
467             SOCK_DGRAM      = 2,
468             SOCK_SEQPACKET  = 5,
469             SOCK_STREAM     = 1
470         }
471 
472         enum
473         {
474             SOL_SOCKET      = 1
475         }
476 
477         enum
478         {
479             SO_ACCEPTCONN   = 30,
480             SO_BROADCAST    = 6,
481             SO_DEBUG        = 1,
482             SO_DONTROUTE    = 5,
483             SO_ERROR        = 4,
484             SO_KEEPALIVE    = 9,
485             SO_LINGER       = 13,
486             SO_OOBINLINE    = 10,
487             SO_RCVBUF       = 8,
488             SO_RCVLOWAT     = 18,
489             SO_RCVTIMEO     = 20,
490             SO_REUSEADDR    = 2,
491             SO_SNDBUF       = 7,
492             SO_SNDLOWAT     = 19,
493             SO_SNDTIMEO     = 21,
494             SO_TYPE         = 3
495         }
496     }
497     else version (IBMZ_Any)
498     {
499         enum
500         {
501             SOCK_DGRAM      = 2,
502             SOCK_SEQPACKET  = 5,
503             SOCK_STREAM     = 1
504         }
505 
506         enum
507         {
508             SOL_SOCKET      = 1
509         }
510 
511         enum
512         {
513             SO_ACCEPTCONN   = 30,
514             SO_BROADCAST    = 6,
515             SO_DEBUG        = 1,
516             SO_DONTROUTE    = 5,
517             SO_ERROR        = 4,
518             SO_KEEPALIVE    = 9,
519             SO_LINGER       = 13,
520             SO_OOBINLINE    = 10,
521             SO_RCVBUF       = 8,
522             SO_RCVLOWAT     = 18,
523             SO_RCVTIMEO     = 20,
524             SO_REUSEADDR    = 2,
525             SO_SNDBUF       = 7,
526             SO_SNDLOWAT     = 19,
527             SO_SNDTIMEO     = 21,
528             SO_TYPE         = 3
529         }
530     }
531     else
532         static assert(0, "unimplemented");
533 
534     version (CRuntime_Glibc)
535     {
536         enum
537         {
538             SOMAXCONN   = 4096
539         }
540     }
541     else
542     {
543         enum
544         {
545             SOMAXCONN   = 128
546         }
547     }
548 
549     enum : uint
550     {
551         MSG_CTRUNC      = 0x08,
552         MSG_DONTROUTE   = 0x04,
553         MSG_EOR         = 0x80,
554         MSG_OOB         = 0x01,
555         MSG_PEEK        = 0x02,
556         MSG_TRUNC       = 0x20,
557         MSG_WAITALL     = 0x100,
558         MSG_NOSIGNAL    = 0x4000
559     }
560 
561     enum
562     {
563         AF_APPLETALK    = 5,
564         AF_INET         = 2,
565         AF_IPX          = 4,
566         AF_UNIX         = 1,
567         AF_UNSPEC       = 0,
568         PF_APPLETALK    = AF_APPLETALK,
569         PF_IPX          = AF_IPX
570     }
571 
572     enum int SOCK_RDM   = 4;
573 
574     enum
575     {
576         SHUT_RD,
577         SHUT_WR,
578         SHUT_RDWR
579     }
580 }
581 else version (Darwin)
582 {
583     alias uint   socklen_t;
584     alias ubyte  sa_family_t;
585 
586     struct sockaddr
587     {
588         ubyte       sa_len;
589         sa_family_t sa_family;
590         byte[14]    sa_data;
591     }
592 
593     private enum : size_t
594     {
595         _SS_PAD1    = long.sizeof - ubyte.sizeof - sa_family_t.sizeof,
596         _SS_PAD2    = 128 - ubyte.sizeof - sa_family_t.sizeof - _SS_PAD1 - long.sizeof
597     }
598 
599     struct sockaddr_storage
600     {
601          ubyte          ss_len;
602          sa_family_t    ss_family;
603          byte[_SS_PAD1] __ss_pad1;
604          long           __ss_align;
605          byte[_SS_PAD2] __ss_pad2;
606     }
607 
608     struct msghdr
609     {
610         void*     msg_name;
611         socklen_t msg_namelen;
612         iovec*    msg_iov;
613         int       msg_iovlen;
614         void*     msg_control;
615         socklen_t msg_controllen;
616         int       msg_flags;
617     }
618 
619     struct cmsghdr
620     {
621         socklen_t  cmsg_len;
622         int        cmsg_level;
623         int        cmsg_type;
624     }
625 
626 
627     extern (D)
628     {
629         socklen_t CMSG_ALIGN(socklen_t len) pure nothrow @nogc { return (len + socklen_t.sizeof - 1) & cast(socklen_t) (~(socklen_t.sizeof - 1)); }
630         socklen_t CMSG_SPACE(socklen_t len) pure nothrow @nogc { return CMSG_ALIGN(len) + CMSG_ALIGN(cmsghdr.sizeof); }
631         socklen_t CMSG_LEN(socklen_t len) pure nothrow @nogc { return CMSG_ALIGN(cmsghdr.sizeof) + len; }
632 
633         inout(ubyte)*   CMSG_DATA( return scope inout(cmsghdr)* cmsg ) pure nothrow @nogc { return cast(ubyte*)( cmsg + 1 ); }
634 
635         inout(cmsghdr)* CMSG_FIRSTHDR( inout(msghdr)* mhdr ) pure nothrow @nogc
636         {
637             return ( cast(socklen_t)mhdr.msg_controllen >= cmsghdr.sizeof ? cast(inout(cmsghdr)*) mhdr.msg_control : cast(inout(cmsghdr)*) null );
638         }
639     }
640 
641     enum : uint
642     {
643         SCM_RIGHTS = 0x01
644     }
645 
646     struct linger
647     {
648         int l_onoff;
649         int l_linger;
650     }
651 
652     enum
653     {
654         SOCK_DGRAM      = 2,
655         SOCK_RDM        = 4,
656         SOCK_SEQPACKET  = 5,
657         SOCK_STREAM     = 1
658     }
659 
660     enum : uint
661     {
662         SOL_SOCKET      = 0xffff
663     }
664 
665     enum : uint
666     {
667         SO_ACCEPTCONN   = 0x0002,
668         SO_BROADCAST    = 0x0020,
669         SO_DEBUG        = 0x0001,
670         SO_DONTROUTE    = 0x0010,
671         SO_ERROR        = 0x1007,
672         SO_KEEPALIVE    = 0x0008,
673         SO_LINGER       = 0x1080,
674         SO_NOSIGPIPE    = 0x1022, // non-standard
675         SO_OOBINLINE    = 0x0100,
676         SO_RCVBUF       = 0x1002,
677         SO_RCVLOWAT     = 0x1004,
678         SO_RCVTIMEO     = 0x1006,
679         SO_REUSEADDR    = 0x0004,
680         SO_REUSEPORT    = 0x0200,
681         SO_SNDBUF       = 0x1001,
682         SO_SNDLOWAT     = 0x1003,
683         SO_SNDTIMEO     = 0x1005,
684         SO_TYPE         = 0x1008
685     }
686 
687     enum
688     {
689         SOMAXCONN       = 128
690     }
691 
692     enum : uint
693     {
694         MSG_CTRUNC      = 0x20,
695         MSG_DONTROUTE   = 0x4,
696         MSG_EOR         = 0x8,
697         MSG_OOB         = 0x1,
698         MSG_PEEK        = 0x2,
699         MSG_TRUNC       = 0x10,
700         MSG_WAITALL     = 0x40
701     }
702 
703     enum
704     {
705         AF_APPLETALK    = 16,
706         AF_INET         = 2,
707         AF_IPX          = 23,
708         AF_UNIX         = 1,
709         AF_UNSPEC       = 0,
710         PF_APPLETALK    = AF_APPLETALK,
711         PF_IPX          = AF_IPX
712     }
713 
714     enum
715     {
716         SHUT_RD,
717         SHUT_WR,
718         SHUT_RDWR
719     }
720 }
721 else version (FreeBSD)
722 {
723     alias uint   socklen_t;
724     alias ubyte  sa_family_t;
725 
726     struct sockaddr
727     {
728         ubyte       sa_len;
729         sa_family_t sa_family;
730         byte[14]    sa_data;
731     }
732 
733     private
734     {
735         enum _SS_ALIGNSIZE  = long.sizeof;
736         enum _SS_MAXSIZE    = 128;
737         enum _SS_PAD1SIZE   = _SS_ALIGNSIZE - ubyte.sizeof - sa_family_t.sizeof;
738         enum _SS_PAD2SIZE   = _SS_MAXSIZE - ubyte.sizeof - sa_family_t.sizeof - _SS_PAD1SIZE - _SS_ALIGNSIZE;
739     }
740 
741     struct sockaddr_storage
742     {
743          ubyte              ss_len;
744          sa_family_t        ss_family;
745          byte[_SS_PAD1SIZE] __ss_pad1;
746          long               __ss_align;
747          byte[_SS_PAD2SIZE] __ss_pad2;
748     }
749 
750     struct msghdr
751     {
752         void*     msg_name;
753         socklen_t msg_namelen;
754         iovec*    msg_iov;
755         int       msg_iovlen;
756         void*     msg_control;
757         socklen_t msg_controllen;
758         int       msg_flags;
759     }
760 
761     struct cmsghdr
762     {
763          socklen_t cmsg_len;
764          int       cmsg_level;
765          int       cmsg_type;
766     }
767 
768     enum : uint
769     {
770         SCM_RIGHTS = 0x01
771     }
772 
773     private // <machine/param.h>
774     {
775         enum _ALIGNBYTES = /+c_int+/ int.sizeof - 1;
776         extern (D) size_t _ALIGN( size_t p ) { return (p + _ALIGNBYTES) & ~_ALIGNBYTES; }
777     }
778 
779     extern (D) ubyte* CMSG_DATA( cmsghdr* cmsg )
780     {
781         return cast(ubyte*) cmsg + _ALIGN( cmsghdr.sizeof );
782     }
783 
784     extern (D) cmsghdr* CMSG_NXTHDR( msghdr* mhdr, cmsghdr* cmsg )
785     {
786         if ( cmsg == null )
787         {
788            return CMSG_FIRSTHDR( mhdr );
789         }
790         else
791         {
792             if ( cast(ubyte*) cmsg + _ALIGN( cmsg.cmsg_len ) + _ALIGN( cmsghdr.sizeof ) >
793                     cast(ubyte*) mhdr.msg_control + mhdr.msg_controllen )
794                 return null;
795             else
796                 return cast(cmsghdr*) (cast(ubyte*) cmsg + _ALIGN( cmsg.cmsg_len ));
797         }
798     }
799 
800     extern (D) cmsghdr* CMSG_FIRSTHDR( msghdr* mhdr )
801     {
802         return mhdr.msg_controllen >= cmsghdr.sizeof ? cast(cmsghdr*) mhdr.msg_control : null;
803     }
804 
805     struct linger
806     {
807         int l_onoff;
808         int l_linger;
809     }
810 
811     enum
812     {
813         SOCK_DGRAM      = 2,
814         SOCK_RDM        = 4,
815         SOCK_SEQPACKET  = 5,
816         SOCK_STREAM     = 1
817     }
818 
819     enum : uint
820     {
821         SOL_SOCKET      = 0xffff
822     }
823 
824     enum : uint
825     {
826         SO_ACCEPTCONN   = 0x0002,
827         SO_BROADCAST    = 0x0020,
828         SO_DEBUG        = 0x0001,
829         SO_DONTROUTE    = 0x0010,
830         SO_ERROR        = 0x1007,
831         SO_KEEPALIVE    = 0x0008,
832         SO_LINGER       = 0x0080,
833         SO_NOSIGPIPE    = 0x0800, // non-standard
834         SO_OOBINLINE    = 0x0100,
835         SO_RCVBUF       = 0x1002,
836         SO_RCVLOWAT     = 0x1004,
837         SO_RCVTIMEO     = 0x1006,
838         SO_REUSEADDR    = 0x0004,
839         SO_REUSEPORT    = 0x0200,
840         SO_SNDBUF       = 0x1001,
841         SO_SNDLOWAT     = 0x1003,
842         SO_SNDTIMEO     = 0x1005,
843         SO_TYPE         = 0x1008
844     }
845 
846     enum
847     {
848         SOMAXCONN       = 128
849     }
850 
851     enum : uint
852     {
853         MSG_CTRUNC      = 0x20,
854         MSG_DONTROUTE   = 0x4,
855         MSG_EOR         = 0x8,
856         MSG_OOB         = 0x1,
857         MSG_PEEK        = 0x2,
858         MSG_TRUNC       = 0x10,
859         MSG_WAITALL     = 0x40,
860         MSG_NOSIGNAL    = 0x20000
861     }
862 
863     enum
864     {
865         AF_APPLETALK    = 16,
866         AF_INET         = 2,
867         AF_IPX          = 23,
868         AF_UNIX         = 1,
869         AF_UNSPEC       = 0
870     }
871 
872     enum
873     {
874         SHUT_RD = 0,
875         SHUT_WR = 1,
876         SHUT_RDWR = 2
877     }
878 }
879 else version (NetBSD)
880 {
881     alias uint   socklen_t;
882     alias ubyte  sa_family_t;
883 
884     struct sockaddr
885     {
886         ubyte       sa_len;
887         sa_family_t sa_family;
888         byte[14]    sa_data;
889     }
890 
891     private
892     {
893         enum _SS_ALIGNSIZE  = long.sizeof;
894         enum _SS_MAXSIZE    = 128;
895         enum _SS_PAD1SIZE   = _SS_ALIGNSIZE - ubyte.sizeof - sa_family_t.sizeof;
896         enum _SS_PAD2SIZE   = _SS_MAXSIZE - ubyte.sizeof - sa_family_t.sizeof - _SS_PAD1SIZE - _SS_ALIGNSIZE;
897     }
898 
899     struct sockaddr_storage
900     {
901          ubyte              ss_len;
902          sa_family_t        ss_family;
903          byte[_SS_PAD1SIZE] __ss_pad1;
904          long               __ss_align;
905          byte[_SS_PAD2SIZE] __ss_pad2;
906     }
907 
908     struct msghdr
909     {
910         void*     msg_name;
911         socklen_t msg_namelen;
912         iovec*    msg_iov;
913         int       msg_iovlen;
914         void*     msg_control;
915         socklen_t msg_controllen;
916         int       msg_flags;
917     }
918 
919     struct cmsghdr
920     {
921          socklen_t cmsg_len;
922          int       cmsg_level;
923          int       cmsg_type;
924     }
925 
926     enum : uint
927     {
928         SCM_RIGHTS = 0x01
929     }
930 
931     private // <machine/param.h>
932     {
933         enum _ALIGNBYTES = /+c_int+/ int.sizeof - 1;
934         extern (D) size_t _ALIGN( size_t p ) { return (p + _ALIGNBYTES) & ~_ALIGNBYTES; }
935     }
936 
937     extern (D) ubyte* CMSG_DATA( cmsghdr* cmsg )
938     {
939         return cast(ubyte*) cmsg + _ALIGN( cmsghdr.sizeof );
940     }
941 
942     extern (D) cmsghdr* CMSG_NXTHDR( msghdr* mhdr, cmsghdr* cmsg )
943     {
944         if ( cmsg == null )
945         {
946            return CMSG_FIRSTHDR( mhdr );
947         }
948         else
949         {
950             if ( cast(ubyte*) cmsg + _ALIGN( cmsg.cmsg_len ) + _ALIGN( cmsghdr.sizeof ) >
951                     cast(ubyte*) mhdr.msg_control + mhdr.msg_controllen )
952                 return null;
953             else
954                 return cast(cmsghdr*) (cast(ubyte*) cmsg + _ALIGN( cmsg.cmsg_len ));
955         }
956     }
957 
958     extern (D) cmsghdr* CMSG_FIRSTHDR( msghdr* mhdr )
959     {
960         return mhdr.msg_controllen >= cmsghdr.sizeof ? cast(cmsghdr*) mhdr.msg_control : null;
961     }
962 
963     struct linger
964     {
965         int l_onoff;
966         int l_linger;
967     }
968 
969     enum
970     {
971         SOCK_DGRAM      = 2,
972         SOCK_RDM        = 4,
973         SOCK_SEQPACKET  = 5,
974         SOCK_STREAM     = 1
975     }
976 
977     enum : uint
978     {
979         SOL_SOCKET      = 0xffff
980     }
981 
982     enum : uint
983     {
984          SO_DEBUG        = 0x0001,          /* turn on debugging info recording */
985          SO_ACCEPTCONN   = 0x0002,          /* socket has had listen() */
986          SO_REUSEADDR    = 0x0004,          /* allow local address reuse */
987          SO_KEEPALIVE    = 0x0008,          /* keep connections alive */
988          SO_DONTROUTE    = 0x0010,          /* just use interface addresses */
989          SO_BROADCAST    = 0x0020,          /* permit sending of broadcast msgs */
990          SO_USELOOPBACK  = 0x0040,          /* bypass hardware when possible */
991          SO_LINGER       = 0x0080,          /* linger on close if data present */
992          SO_OOBINLINE    = 0x0100,          /* leave received OOB data in line */
993          SO_REUSEPORT    = 0x0200,          /* allow local address & port reuse */
994         /*      SO_OTIMESTAMP   0x0400          */
995          SO_NOSIGPIPE    = 0x0800,          /* no SIGPIPE from EPIPE */
996          SO_ACCEPTFILTER = 0x1000,          /* there is an accept filter */
997          SO_TIMESTAMP    = 0x2000,          /* timestamp received dgram traffic */
998 
999         /*
1000          * Additional options, not kept in so_options.
1001          */
1002          SO_SNDBUF       = 0x1001,          /* send buffer size */
1003          SO_RCVBUF       = 0x1002,          /* receive buffer size */
1004          SO_SNDLOWAT     = 0x1003,          /* send low-water mark */
1005          SO_RCVLOWAT     = 0x1004,          /* receive low-water mark */
1006         /* SO_OSNDTIMEO         0x1005 */
1007         /* SO_ORCVTIMEO         0x1006 */
1008          SO_ERROR        = 0x1007,          /* get error status and clear */
1009          SO_TYPE         = 0x1008,          /* get socket type */
1010          SO_OVERFLOWED   = 0x1009,          /* datagrams: return packets dropped */
1011 
1012          SO_NOHEADER     = 0x100a,          /* user supplies no header to kernel;
1013                                                  * kernel removes header and supplies
1014                                                  * payload
1015                                                  */
1016          SO_SNDTIMEO     = 0x100b,          /* send timeout */
1017          SO_RCVTIMEO     = 0x100c          /* receive timeout */
1018 
1019     }
1020 
1021     enum
1022     {
1023         SOMAXCONN       = 128
1024     }
1025 
1026     enum : uint
1027     {
1028          MSG_OOB         = 0x0001,          /* process out-of-band data */
1029          MSG_PEEK        = 0x0002,          /* peek at incoming message */
1030          MSG_DONTROUTE   = 0x0004,          /* send without using routing tables */
1031          MSG_EOR         = 0x0008,          /* data completes record */
1032          MSG_TRUNC       = 0x0010,          /* data discarded before delivery */
1033          MSG_CTRUNC      = 0x0020,          /* control data lost before delivery */
1034          MSG_WAITALL     = 0x0040,          /* wait for full request or error */
1035          MSG_DONTWAIT    = 0x0080,          /* this message should be nonblocking */
1036          MSG_BCAST       = 0x0100,          /* this message was rcvd using link-level brdcst */
1037          MSG_MCAST       = 0x0200,          /* this message was rcvd using link-level mcast */
1038          MSG_NOSIGNAL    = 0x0400          /* do not generate SIGPIPE on EOF */
1039     }
1040 
1041     enum
1042     {
1043         AF_APPLETALK    = 16,
1044         AF_INET         = 2,
1045         AF_IPX          = 23,
1046         AF_UNIX         = 1,
1047         AF_UNSPEC       = 0
1048     }
1049 
1050     enum
1051     {
1052         SHUT_RD = 0,
1053         SHUT_WR = 1,
1054         SHUT_RDWR = 2
1055     }
1056 }
1057 else version (OpenBSD)
1058 {
1059     alias uint   socklen_t;
1060     alias ubyte  sa_family_t;
1061 
1062     struct sockaddr
1063     {
1064         ubyte       sa_len;
1065         sa_family_t sa_family;
1066         byte[14]    sa_data;
1067     }
1068 
1069     struct sockaddr_storage
1070     {
1071          ubyte       ss_len;
1072          sa_family_t ss_family;
1073          ubyte[6]    __ss_pad1;
1074          long        __ss_align;
1075          ubyte[240]  __ss_pad2;
1076     }
1077 
1078     struct msghdr
1079     {
1080         void*     msg_name;
1081         socklen_t msg_namelen;
1082         iovec*    msg_iov;
1083         uint      msg_iovlen;
1084         void*     msg_control;
1085         socklen_t msg_controllen;
1086         int       msg_flags;
1087     }
1088 
1089     struct cmsghdr
1090     {
1091          socklen_t cmsg_len;
1092          int       cmsg_level;
1093          int       cmsg_type;
1094     }
1095 
1096     enum : uint
1097     {
1098         SCM_RIGHTS    = 0x01,
1099         SCM_TIMESTAMP = 0x04
1100     }
1101 
1102     private // <sys/_types.h>
1103     {
1104         enum _ALIGNBYTES = c_long.sizeof - 1;
1105         extern (D) size_t _ALIGN(size_t p) pure nothrow @nogc
1106         {
1107             return (p + _ALIGNBYTES) & ~_ALIGNBYTES;
1108         }
1109     }
1110 
1111     extern (D) ubyte* CMSG_DATA(cmsghdr* cmsg) pure nothrow @nogc
1112     {
1113         return cast(ubyte*) cmsg + _ALIGN(cmsghdr.sizeof);
1114     }
1115 
1116     extern (D) cmsghdr* CMSG_NXTHDR(msghdr* mhdr, cmsghdr* cmsg) pure nothrow @nogc
1117     {
1118         if (cast(ubyte*) cmsg + _ALIGN(cmsg.cmsg_len) + _ALIGN(cmsghdr.sizeof) >
1119                 cast(ubyte*) mhdr.msg_control + mhdr.msg_controllen)
1120             return null;
1121         else
1122             return cast(cmsghdr*) (cast(ubyte*) cmsg + _ALIGN(cmsg.cmsg_len));
1123     }
1124 
1125     extern (D) cmsghdr* CMSG_FIRSTHDR(msghdr* mhdr) pure nothrow @nogc
1126     {
1127         return mhdr.msg_controllen >= cmsghdr.sizeof ? cast(cmsghdr*) mhdr.msg_control : null;
1128     }
1129 
1130     extern (D)
1131     {
1132         size_t CMSG_LEN(size_t len) pure nothrow @nogc
1133         {
1134             return _ALIGN(cmsghdr.sizeof) + len;
1135         }
1136     }
1137 
1138     extern (D) size_t CMSG_SPACE(size_t len) pure nothrow @nogc
1139     {
1140         return _ALIGN(cmsghdr.sizeof) + _ALIGN(len);
1141     }
1142 
1143     struct linger
1144     {
1145         int l_onoff;
1146         int l_linger;
1147     }
1148 
1149     enum
1150     {
1151         SOCK_DGRAM      = 2,
1152         SOCK_RDM        = 4,
1153         SOCK_SEQPACKET  = 5,
1154         SOCK_STREAM     = 1
1155     }
1156 
1157     enum : uint
1158     {
1159         SOL_SOCKET      = 0xffff
1160     }
1161 
1162     enum : uint
1163     {
1164          SO_DEBUG        = 0x0001,
1165          SO_ACCEPTCONN   = 0x0002,
1166          SO_REUSEADDR    = 0x0004,
1167          SO_KEEPALIVE    = 0x0008,
1168          SO_DONTROUTE    = 0x0010,
1169          SO_BROADCAST    = 0x0020,
1170          SO_USELOOPBACK  = 0x0040,
1171          SO_LINGER       = 0x0080,
1172          SO_OOBINLINE    = 0x0100,
1173          SO_REUSEPORT    = 0x0200,
1174          SO_TIMESTAMP    = 0x0800,
1175          SO_BINDANY      = 0x1000,
1176          SO_ZEROSIZE     = 0x2000,
1177 
1178          SO_SNDBUF       = 0x1001,
1179          SO_RCVBUF       = 0x1002,
1180          SO_SNDLOWAT     = 0x1003,
1181          SO_RCVLOWAT     = 0x1004,
1182          SO_SNDTIMEO     = 0x1005,
1183          SO_RCVTIMEO     = 0x1006,
1184          SO_ERROR        = 0x1007,
1185          SO_TYPE         = 0x1008,
1186          SO_NETPROC      = 0x1020,
1187          SO_RTABLE       = 0x1021,
1188          SO_PEERCRED     = 0x1022,
1189          SO_SPLICE       = 0x1023,
1190     }
1191 
1192     enum
1193     {
1194         SOMAXCONN       = 128
1195     }
1196 
1197     enum : uint
1198     {
1199          MSG_OOB          = 0x001,
1200          MSG_PEEK         = 0x002,
1201          MSG_DONTROUTE    = 0x004,
1202          MSG_EOR          = 0x008,
1203          MSG_TRUNC        = 0x010,
1204          MSG_CTRUNC       = 0x020,
1205          MSG_WAITALL      = 0x040,
1206          MSG_DONTWAIT     = 0x080,
1207          MSG_BCAST        = 0x100,
1208          MSG_MCAST        = 0x200,
1209          MSG_NOSIGNAL     = 0x400,
1210          MSG_CMSG_CLOEXEC = 0x800,
1211     }
1212 
1213     enum
1214     {
1215         AF_APPLETALK    = 16,
1216         AF_INET         = 2,
1217         AF_IPX          = 23,
1218         AF_UNIX         = 1,
1219         AF_UNSPEC       = 0
1220     }
1221 
1222     enum
1223     {
1224         SHUT_RD = 0,
1225         SHUT_WR = 1,
1226         SHUT_RDWR = 2
1227     }
1228 }
1229 else version (DragonFlyBSD)
1230 {
1231     alias uint   socklen_t;
1232     alias ubyte  sa_family_t;
1233 
1234     enum
1235     {
1236         SOCK_STREAM         = 1,
1237         SOCK_DGRAM          = 2,
1238         //SOCK_RAW          = 3,      // defined below
1239         SOCK_RDM            = 4,
1240         SOCK_SEQPACKET      = 5,
1241     }
1242 
1243     enum SOCK_CLOEXEC       = 0x10000000;
1244     enum SOCK_NONBLOCK      = 0x20000000;
1245 
1246     enum : uint
1247     {
1248         SO_DEBUG            = 0x0001,
1249         SO_ACCEPTCONN       = 0x0002,
1250         SO_REUSEADDR        = 0x0004,
1251         SO_KEEPALIVE        = 0x0008,
1252         SO_DONTROUTE        = 0x0010,
1253         SO_BROADCAST        = 0x0020,
1254         SO_USELOOPBACK      = 0x0040,
1255         SO_LINGER           = 0x0080,
1256         SO_OOBINLINE        = 0x0100,
1257         SO_REUSEPORT        = 0x0200,
1258         SO_TIMESTAMP        = 0x0400,
1259         SO_NOSIGPIPE        = 0x0800, // non-standard
1260         SO_ACCEPTFILTER     = 0x1000,
1261 
1262         SO_SNDBUF           = 0x1001,
1263         SO_RCVBUF           = 0x1002,
1264         SO_SNDLOWAT         = 0x1003,
1265         SO_RCVLOWAT         = 0x1004,
1266         SO_SNDTIMEO         = 0x1005,
1267         SO_RCVTIMEO         = 0x1006,
1268         SO_ERROR            = 0x1007,
1269         SO_TYPE             = 0x1008,
1270         SO_SNDSPACE         = 0x100a, // get appr. send buffer free space
1271         SO_CPUHINT          = 0x1030, // get socket's owner cpuid hint
1272     }
1273 
1274     struct linger
1275     {
1276         int l_onoff;
1277         int l_linger;
1278     }
1279 
1280     struct  accept_filter_arg {
1281         byte[16] af_name;
1282         byte[256-16] af_arg;
1283     }
1284 
1285     enum : uint
1286     {
1287         SOL_SOCKET          = 0xffff
1288     }
1289 
1290     enum
1291     {
1292         AF_UNSPEC           = 0,
1293         AF_LOCAL            = 1,
1294         AF_UNIX             = AF_LOCAL,
1295         AF_INET             = 2,
1296         AF_APPLETALK        = 16,
1297         AF_IPX              = 23,
1298     }
1299 
1300     struct sockaddr
1301     {
1302         ubyte               sa_len;
1303         sa_family_t         sa_family;
1304         byte[14]            sa_data;
1305     }
1306 
1307     enum SOCK_MAXADDRLEN = 255;
1308 
1309     struct sockproto {
1310         ushort              sp_family;
1311         ushort              sp_protocol;
1312     }
1313 
1314     private
1315     {
1316         enum _SS_ALIGNSIZE  = long.sizeof;
1317         enum _SS_MAXSIZE    = 128;
1318         enum _SS_PAD1SIZE   = _SS_ALIGNSIZE - ubyte.sizeof - sa_family_t.sizeof;
1319         enum _SS_PAD2SIZE   = _SS_MAXSIZE - ubyte.sizeof - sa_family_t.sizeof - _SS_PAD1SIZE - _SS_ALIGNSIZE;
1320     }
1321 
1322     struct sockaddr_storage
1323     {
1324         ubyte              ss_len;
1325         sa_family_t        ss_family;
1326         byte[_SS_PAD1SIZE] __ss_pad1;
1327         long               __ss_align;
1328         byte[_SS_PAD2SIZE] __ss_pad2;
1329     }
1330 
1331     struct msghdr
1332     {
1333         void*               msg_name;
1334         socklen_t           msg_namelen;
1335         iovec*              msg_iov;
1336         int                 msg_iovlen;
1337         void*               msg_control;
1338         socklen_t           msg_controllen;
1339         int                 msg_flags;
1340     }
1341 
1342     enum SOMAXCONN          = 128;
1343     enum SOMAXOPT_SIZE      = 65536;
1344     enum SOMAXOPT_SIZE0     = (32 * 1024 * 1024);
1345 
1346     enum : uint
1347     {
1348         MSG_OOB             = 0x00000001,
1349         MSG_PEEK            = 0x00000002,
1350         MSG_DONTROUTE       = 0x00000004,
1351         MSG_EOR             = 0x00000008,
1352         MSG_TRUNC           = 0x00000010,
1353         MSG_CTRUNC          = 0x00000020,
1354         MSG_WAITALL         = 0x00000040,
1355         MSG_DONTWAIT        = 0x00000080,
1356         MSG_EOF             = 0x00000100,
1357         MSG_UNUSED09        = 0x00000200,
1358         MSG_NOSIGNAL        = 0x00000400,
1359         MSG_SYNC            = 0x00000800,
1360         MSG_CMSG_CLOEXEC    = 0x00001000,
1361         /* These override FIONBIO.  MSG_FNONBLOCKING is functionally equivalent to MSG_DONTWAIT.*/
1362         MSG_FBLOCKING       = 0x00010000,
1363         MSG_FNONBLOCKING    = 0x00020000,
1364         MSG_FMASK           = 0xFFFF0000,
1365     }
1366 
1367     struct cmsghdr
1368     {
1369          socklen_t          cmsg_len;
1370          int                cmsg_level;
1371          int                cmsg_type;
1372     }
1373 
1374     enum CMGROUP_MAX        = 16;
1375 
1376     struct cmsgcred {
1377             pid_t           cmcred_pid;
1378             uid_t           cmcred_uid;
1379             uid_t           cmcred_euid;
1380             gid_t           cmcred_gid;
1381             short           cmcred_ngroups;
1382             gid_t[CMGROUP_MAX] cmcred_groups;
1383     }
1384 
1385     enum : uint
1386     {
1387         SCM_RIGHTS = 0x01
1388     }
1389 
1390     private // <machine/param.h>
1391     {
1392         enum _ALIGNBYTES = /+c_int+/ int.sizeof - 1;
1393         extern (D) size_t _ALIGN( size_t p ) { return (p + _ALIGNBYTES) & ~_ALIGNBYTES; }
1394     }
1395 
1396     extern (D) ubyte* CMSG_DATA( cmsghdr* cmsg )
1397     {
1398         return cast(ubyte*) cmsg + _ALIGN( cmsghdr.sizeof );
1399     }
1400 
1401     extern (D) cmsghdr* CMSG_NXTHDR( msghdr* mhdr, cmsghdr* cmsg )
1402     {
1403         if ( cmsg == null )
1404         {
1405            return CMSG_FIRSTHDR( mhdr );
1406         }
1407         else
1408         {
1409             if ( cast(ubyte*) cmsg + _ALIGN( cmsg.cmsg_len ) + _ALIGN( cmsghdr.sizeof ) >
1410                     cast(ubyte*) mhdr.msg_control + mhdr.msg_controllen )
1411                 return null;
1412             else
1413                 return cast(cmsghdr*) (cast(ubyte*) cmsg + _ALIGN( cmsg.cmsg_len ));
1414         }
1415     }
1416 
1417     extern (D) cmsghdr* CMSG_FIRSTHDR( msghdr* mhdr )
1418     {
1419         return mhdr.msg_controllen >= cmsghdr.sizeof ? cast(cmsghdr*) mhdr.msg_control : null;
1420     }
1421 
1422     enum
1423     {
1424         SHUT_RD             = 0,
1425         SHUT_WR             = 1,
1426         SHUT_RDWR           = 2
1427     }
1428 }
1429 else version (Solaris)
1430 {
1431     alias uint socklen_t;
1432     alias ushort sa_family_t;
1433 
1434     struct sockaddr
1435     {
1436         sa_family_t sa_family;
1437         char[14] sa_data = 0;
1438     }
1439 
1440     alias double sockaddr_maxalign_t;
1441 
1442     private
1443     {
1444         enum _SS_ALIGNSIZE  = sockaddr_maxalign_t.sizeof;
1445         enum _SS_MAXSIZE    = 256;
1446         enum _SS_PAD1SIZE   = _SS_ALIGNSIZE - sa_family_t.sizeof;
1447         enum _SS_PAD2SIZE   = _SS_MAXSIZE - sa_family_t.sizeof + _SS_PAD1SIZE + _SS_ALIGNSIZE;
1448     }
1449 
1450     struct sockaddr_storage
1451     {
1452          sa_family_t ss_family;
1453          char[_SS_PAD1SIZE] _ss_pad1 = void;
1454          sockaddr_maxalign_t _ss_align;
1455          char[_SS_PAD2SIZE] _ss_pad2 = void;
1456     }
1457 
1458     struct msghdr
1459     {
1460         void* msg_name;
1461         socklen_t msg_namelen;
1462         iovec* msg_iov;
1463         int msg_iovlen;
1464         void* msg_control;
1465         socklen_t msg_controllen;
1466         int msg_flags;
1467     }
1468 
1469     struct cmsghdr
1470     {
1471          socklen_t cmsg_len;
1472          int cmsg_level;
1473          int cmsg_type;
1474     }
1475 
1476     enum : uint
1477     {
1478         SCM_RIGHTS = 0x1010
1479     }
1480 
1481     // FIXME: CMSG_DATA, CMSG_NXTHDR, CMSG_FIRSTHDR missing
1482 
1483     struct linger
1484     {
1485         int l_onoff;
1486         int l_linger;
1487     }
1488 
1489     enum
1490     {
1491         SOCK_STREAM = 2,
1492         SOCK_DGRAM = 1,
1493         SOCK_RDM = 5,
1494         SOCK_SEQPACKET = 6,
1495     }
1496 
1497     enum : uint
1498     {
1499         SOL_SOCKET      = 0xffff
1500     }
1501 
1502     enum : uint
1503     {
1504         SO_ACCEPTCONN   = 0x0002,
1505         SO_BROADCAST    = 0x0020,
1506         SO_DEBUG        = 0x0001,
1507         SO_DONTROUTE    = 0x0010,
1508         SO_ERROR        = 0x1007,
1509         SO_KEEPALIVE    = 0x0008,
1510         SO_LINGER       = 0x0080,
1511         SO_OOBINLINE    = 0x0100,
1512         SO_RCVBUF       = 0x1002,
1513         SO_RCVLOWAT     = 0x1004,
1514         SO_RCVTIMEO     = 0x1006,
1515         SO_REUSEADDR    = 0x0004,
1516         SO_SNDBUF       = 0x1001,
1517         SO_SNDLOWAT     = 0x1003,
1518         SO_SNDTIMEO     = 0x1005,
1519         SO_TYPE         = 0x1008,
1520 
1521         SO_USELOOPBACK  = 0x0040, // non-standard
1522         SO_DGRAM_ERRIND = 0x0200, // non-standard
1523         SO_RECVUCRED    = 0x0400, // non-standard
1524     }
1525 
1526     enum
1527     {
1528         SOMAXCONN = 128
1529     }
1530 
1531     enum : uint
1532     {
1533         MSG_CTRUNC      = 0x10,
1534         MSG_DONTROUTE   = 0x4,
1535         MSG_EOR         = 0x8,
1536         MSG_OOB         = 0x1,
1537         MSG_PEEK        = 0x2,
1538         MSG_TRUNC       = 0x20,
1539         MSG_WAITALL     = 0x40
1540     }
1541 
1542     enum
1543     {
1544         AF_IPX          = 23,
1545         AF_APPLETALK    = 16,
1546         AF_INET         = 2,
1547         AF_UNIX         = 1,
1548         AF_UNSPEC       = 0
1549     }
1550 
1551     enum
1552     {
1553         SHUT_RD,
1554         SHUT_WR,
1555         SHUT_RDWR
1556     }
1557 }
1558 else
1559 {
1560     static assert(false, "Unsupported platform");
1561 }
1562 
1563 /*
1564 int     accept(int, sockaddr*, socklen_t*);
1565 int     bind(int, const scope sockaddr*, socklen_t);
1566 int     connect(int, const scope sockaddr*, socklen_t);
1567 int     getpeername(int, sockaddr*, socklen_t*);
1568 int     getsockname(int, sockaddr*, socklen_t*);
1569 int     getsockopt(int, int, int, void*, socklen_t*);
1570 int     listen(int, int);
1571 ssize_t recv(int, void*, size_t, int);
1572 ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*);
1573 ssize_t recvmsg(int, msghdr*, int);
1574 ssize_t send(int, const scope void*, size_t, int);
1575 ssize_t sendmsg(int, const scope msghdr*, int);
1576 ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
1577 int     setsockopt(int, int, int, const scope void*, socklen_t);
1578 int     shutdown(int, int);
1579 int     socket(int, int, int);
1580 int     sockatmark(int);
1581 int     socketpair(int, int, int, ref int[2]);
1582 */
1583 
1584 version (CRuntime_Glibc)
1585 {
1586     int     accept(int, scope sockaddr*, scope socklen_t*);
1587     int     bind(int, const scope sockaddr*, socklen_t);
1588     int     connect(int, const scope sockaddr*, socklen_t);
1589     int     getpeername(int, scope sockaddr*, scope socklen_t*);
1590     int     getsockname(int, scope sockaddr*, scope socklen_t*);
1591     int     getsockopt(int, int, int, scope void*, scope socklen_t*);
1592     int     listen(int, int) @safe;
1593     ssize_t recv(int, scope void*, size_t, int);
1594     ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*);
1595     ssize_t recvmsg(int, scope msghdr*, int);
1596     ssize_t send(int, const scope void*, size_t, int);
1597     ssize_t sendmsg(int, const scope msghdr*, int);
1598     ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
1599     int     setsockopt(int, int, int, const scope void*, socklen_t);
1600     int     shutdown(int, int) @safe;
1601     int     socket(int, int, int) @safe;
1602     int     sockatmark(int) @safe;
1603     int     socketpair(int, int, int, ref int[2]) @safe;
1604 }
1605 else version (Darwin)
1606 {
1607     int     accept(int, scope sockaddr*, scope socklen_t*);
1608     int     bind(int, const scope sockaddr*, socklen_t);
1609     int     connect(int, const scope sockaddr*, socklen_t);
1610     int     getpeername(int, scope sockaddr*, scope socklen_t*);
1611     int     getsockname(int, scope sockaddr*, scope socklen_t*);
1612     int     getsockopt(int, int, int, scope void*, scope socklen_t*);
1613     int     listen(int, int) @safe;
1614     ssize_t recv(int, scope void*, size_t, int);
1615     ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*);
1616     ssize_t recvmsg(int, scope msghdr*, int);
1617     ssize_t send(int, const scope void*, size_t, int);
1618     ssize_t sendmsg(int, const scope msghdr*, int);
1619     ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
1620     int     setsockopt(int, int, int, const scope void*, socklen_t);
1621     int     shutdown(int, int) @safe;
1622     int     socket(int, int, int) @safe;
1623     int     sockatmark(int) @safe;
1624     int     socketpair(int, int, int, ref int[2]) @safe;
1625 }
1626 else version (FreeBSD)
1627 {
1628     int     accept(int, scope sockaddr*, scope socklen_t*);
1629     int     bind(int, const scope sockaddr*, socklen_t);
1630     int     connect(int, const scope sockaddr*, socklen_t);
1631     int     getpeername(int, scope sockaddr*, scope socklen_t*);
1632     int     getsockname(int, scope sockaddr*, scope socklen_t*);
1633     int     getsockopt(int, int, int, scope void*, scope socklen_t*);
1634     int     listen(int, int) @safe;
1635     ssize_t recv(int, scope void*, size_t, int);
1636     ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*);
1637     ssize_t recvmsg(int, scope msghdr*, int);
1638     ssize_t send(int, const scope void*, size_t, int);
1639     ssize_t sendmsg(int, const scope msghdr*, int);
1640     ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
1641     int     setsockopt(int, int, int, const scope void*, socklen_t);
1642     int     shutdown(int, int) @safe;
1643     int     socket(int, int, int) @safe;
1644     int     sockatmark(int) @safe;
1645     int     socketpair(int, int, int, ref int[2]) @safe;
1646 }
1647 else version (NetBSD)
1648 {
1649     int     accept(int, scope sockaddr*, scope socklen_t*);
1650     int     bind(int, const scope sockaddr*, socklen_t);
1651     int     connect(int, const scope sockaddr*, socklen_t);
1652     int     getpeername(int, scope sockaddr*, scope socklen_t*);
1653     int     getsockname(int, scope sockaddr*, scope socklen_t*);
1654     int     getsockopt(int, int, int, scope void*, scope socklen_t*);
1655     int     listen(int, int) @safe;
1656     ssize_t recv(int, scope void*, size_t, int);
1657     ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*);
1658     ssize_t recvmsg(int, scope msghdr*, int);
1659     ssize_t send(int, const scope void*, size_t, int);
1660     ssize_t sendmsg(int, const scope msghdr*, int);
1661     ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
1662     int     setsockopt(int, int, int, const scope void*, socklen_t);
1663     int     shutdown(int, int) @safe;
1664     int     socket(int, int, int) @safe;
1665     int     sockatmark(int) @safe;
1666     int     socketpair(int, int, int, ref int[2]) @safe;
1667 }
1668 else version (OpenBSD)
1669 {
1670     int     accept(int, scope sockaddr*, scope socklen_t*);
1671     int     bind(int, const scope sockaddr*, socklen_t);
1672     int     connect(int, const scope sockaddr*, socklen_t);
1673     int     getpeername(int, scope sockaddr*, scope socklen_t*);
1674     int     getsockname(int, scope sockaddr*, scope socklen_t*);
1675     int     getsockopt(int, int, int, scope void*, scope socklen_t*);
1676     int     listen(int, int) @safe;
1677     ssize_t recv(int, scope void*, size_t, int);
1678     ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*);
1679     ssize_t recvmsg(int, scope msghdr*, int);
1680     ssize_t send(int, const scope void*, size_t, int);
1681     ssize_t sendmsg(int, const scope msghdr*, int);
1682     ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
1683     int     setsockopt(int, int, int, const scope void*, socklen_t);
1684     int     shutdown(int, int) @safe;
1685     int     socket(int, int, int) @safe;
1686     int     sockatmark(int) @safe;
1687     int     socketpair(int, int, int, ref int[2]) @safe;
1688 }
1689 else version (DragonFlyBSD)
1690 {
1691     int     accept(int, sockaddr*, socklen_t*);
1692 //    int     accept4(int, sockaddr*, socklen_t*, int);
1693     int     bind(int, const scope sockaddr*, socklen_t);
1694     int     connect(int, const scope sockaddr*, socklen_t);
1695 //    int     extconnect(int, int, sockaddr*, socklen_t);
1696     int     getpeername(int, sockaddr*, socklen_t*);
1697     int     getsockname(int, sockaddr*, socklen_t*);
1698     int     getsockopt(int, int, int, void*, socklen_t*);
1699     int     listen(int, int);
1700     ssize_t recv(int, void*, size_t, int);
1701     ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*);
1702     ssize_t recvmsg(int, msghdr*, int);
1703     ssize_t send(int, const scope void*, size_t, int);
1704     ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
1705     ssize_t sendmsg(int, const scope msghdr*, int);
1706 //    int     sendfile(int, int, off_t, size_t, sf_hdtr *, off_t *, int);
1707     int     setsockopt(int, int, int, const scope void*, socklen_t);
1708     int     shutdown(int, int);
1709     int     sockatmark(int);
1710     int     socket(int, int, int);
1711     int     socketpair(int, int, int, ref int[2]);
1712 //  void    pfctlinput(int, struct sockaddr *);
1713 }
1714 else version (Solaris)
1715 {
1716     int     accept(int, scope sockaddr*, scope socklen_t*);
1717     int     bind(int, const scope sockaddr*, socklen_t);
1718     int     connect(int, const scope sockaddr*, socklen_t);
1719     int     getpeername(int, scope sockaddr*, scope socklen_t*);
1720     int     getsockname(int, scope sockaddr*, scope socklen_t*);
1721     int     getsockopt(int, int, int, scope void*, scope socklen_t*);
1722     int     listen(int, int) @safe;
1723     ssize_t recv(int, scope void*, size_t, int);
1724     ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*);
1725     ssize_t recvmsg(int, scope msghdr*, int);
1726     ssize_t send(int, const scope void*, size_t, int);
1727     ssize_t sendmsg(int, const scope msghdr*, int);
1728     ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
1729     int     setsockopt(int, int, int, const scope void*, socklen_t);
1730     int     shutdown(int, int) @safe;
1731     int     socket(int, int, int) @safe;
1732     int     sockatmark(int) @safe;
1733     int     socketpair(int, int, int, ref int[2]) @safe;
1734 }
1735 else version (CRuntime_Bionic)
1736 {
1737     int     accept(int, scope sockaddr*, scope socklen_t*);
1738     int     bind(int, const scope sockaddr*, socklen_t);
1739     int     connect(int, const scope sockaddr*, socklen_t);
1740     int     getpeername(int, scope sockaddr*, scope socklen_t*);
1741     int     getsockname(int, scope sockaddr*, scope socklen_t*);
1742     int     getsockopt(int, int, int, scope void*, scope socklen_t*);
1743     int     listen(int, int) @safe;
1744     ssize_t recv(int, scope void*, size_t, int);
1745     ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*);
1746     int     recvmsg(int, scope msghdr*, int);
1747     ssize_t send(int, const scope void*, size_t, int);
1748     int     sendmsg(int, const scope msghdr*, int);
1749     ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
1750     int     setsockopt(int, int, int, const scope void*, socklen_t);
1751     int     shutdown(int, int) @safe;
1752     int     socket(int, int, int) @safe;
1753     int     sockatmark(int) @safe;
1754     int     socketpair(int, int, int, ref int[2]) @safe;
1755 }
1756 else version (CRuntime_Musl)
1757 {
1758     int     accept(int, sockaddr*, socklen_t*);
1759     int     bind(int, const scope sockaddr*, socklen_t);
1760     int     connect(int, const scope sockaddr*, socklen_t);
1761     int     getpeername(int, sockaddr*, socklen_t*);
1762     int     getsockname(int, sockaddr*, socklen_t*);
1763     int     getsockopt(int, int, int, void*, socklen_t*);
1764     int     listen(int, int);
1765     ssize_t recv(int, void*, size_t, int);
1766     ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*);
1767     ssize_t recvmsg(int, msghdr*, int);
1768     ssize_t send(int, const scope void*, size_t, int);
1769     ssize_t sendmsg(int, const scope msghdr*, int);
1770     ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
1771     int     setsockopt(int, int, int, const scope void*, socklen_t);
1772     int     shutdown(int, int);
1773     int     socket(int, int, int);
1774     int     sockatmark(int);
1775     int     socketpair(int, int, int, ref int[2]);
1776 }
1777 else version (CRuntime_UClibc)
1778 {
1779     int     accept(int, sockaddr*, socklen_t*);
1780     int     bind(int, const scope sockaddr*, socklen_t);
1781     int     connect(int, const scope sockaddr*, socklen_t);
1782     int     getpeername(int, sockaddr*, socklen_t*);
1783     int     getsockname(int, sockaddr*, socklen_t*);
1784     int     getsockopt(int, int, int, void*, socklen_t*);
1785     int     listen(int, int);
1786     ssize_t recv(int, void*, size_t, int);
1787     ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*);
1788     ssize_t recvmsg(int, msghdr*, int);
1789     ssize_t send(int, const scope void*, size_t, int);
1790     ssize_t sendmsg(int, const scope msghdr*, int);
1791     ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);
1792     int     setsockopt(int, int, int, const scope void*, socklen_t);
1793     int     shutdown(int, int);
1794     int     socket(int, int, int);
1795     int     sockatmark(int);
1796     int     socketpair(int, int, int, ref int[2]);
1797 }
1798 else
1799 {
1800     static assert(false, "Unsupported platform");
1801 }
1802 
1803 //
1804 // IPV6 (IP6)
1805 //
1806 /*
1807 AF_INET6
1808 */
1809 
1810 version (linux)
1811 {
1812     enum
1813     {
1814         AF_INET6    = 10
1815     }
1816 }
1817 else version (Darwin)
1818 {
1819     enum
1820     {
1821         AF_INET6    = 30
1822     }
1823 }
1824 else version (FreeBSD)
1825 {
1826     enum
1827     {
1828         AF_INET6    = 28
1829     }
1830 }
1831 else version (NetBSD)
1832 {
1833     enum
1834     {
1835         AF_INET6    = 24
1836     }
1837 }
1838 else version (OpenBSD)
1839 {
1840     enum
1841     {
1842         AF_INET6    = 24
1843     }
1844 }
1845 else version (DragonFlyBSD)
1846 {
1847     enum
1848     {
1849         AF_INET6    = 28
1850     }
1851 }
1852 else version (Solaris)
1853 {
1854     enum
1855     {
1856         AF_INET6 = 26,
1857     }
1858 }
1859 else
1860 {
1861     static assert(false, "Unsupported platform");
1862 }
1863 
1864 //
1865 // Raw Sockets (RS)
1866 //
1867 /*
1868 SOCK_RAW
1869 */
1870 
1871 version (linux)
1872 {
1873     enum
1874     {
1875         SOCK_RAW    = 3
1876     }
1877 }
1878 else version (Darwin)
1879 {
1880     enum
1881     {
1882         SOCK_RAW    = 3
1883     }
1884 }
1885 else version (FreeBSD)
1886 {
1887     enum
1888     {
1889         SOCK_RAW    = 3
1890     }
1891 }
1892 else version (NetBSD)
1893 {
1894     enum
1895     {
1896         SOCK_RAW    = 3
1897     }
1898 }
1899 else version (OpenBSD)
1900 {
1901     enum
1902     {
1903         SOCK_RAW    = 3
1904     }
1905 }
1906 else version (DragonFlyBSD)
1907 {
1908     enum
1909     {
1910         SOCK_RAW    = 3
1911     }
1912 }
1913 else version (Solaris)
1914 {
1915     enum
1916     {
1917         SOCK_RAW = 4,
1918     }
1919 }
1920 else
1921 {
1922     static assert(false, "Unsupported platform");
1923 }