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
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.netinet.in_;
16 
17 import core.sys.posix.config;
18 public import core.stdc.inttypes; // for uint32_t, uint16_t, uint8_t
19 public import core.sys.posix.arpa.inet;
20 public import core.sys.posix.sys.socket; // for sa_family_t
21 
22 version (OSX)
23     version = Darwin;
24 else version (iOS)
25     version = Darwin;
26 else version (TVOS)
27     version = Darwin;
28 else version (WatchOS)
29     version = Darwin;
30 
31 version (Posix):
32 extern (C) nothrow @nogc:
33 
34 //
35 // Required
36 //
37 /*
38 NOTE: The following must must be defined in core.sys.posix.arpa.inet to break
39       a circular import: in_port_t, in_addr_t, struct in_addr, INET_ADDRSTRLEN.
40 
41 in_port_t
42 in_addr_t
43 
44 sa_family_t // from core.sys.posix.sys.socket
45 uint8_t     // from core.stdc.inttypes
46 uint32_t    // from core.stdc.inttypes
47 
48 struct in_addr
49 {
50     in_addr_t   s_addr;
51 }
52 
53 struct sockaddr_in
54 {
55     sa_family_t sin_family;
56     in_port_t   sin_port;
57     in_addr     sin_addr;
58 }
59 
60 IPPROTO_IP
61 IPPROTO_ICMP
62 IPPROTO_TCP
63 IPPROTO_UDP
64 
65 INADDR_ANY
66 INADDR_BROADCAST
67 
68 INET_ADDRSTRLEN
69 
70 htonl() // from core.sys.posix.arpa.inet
71 htons() // from core.sys.posix.arpa.inet
72 ntohl() // from core.sys.posix.arpa.inet
73 ntohs() // from core.sys.posix.arpa.inet
74 */
75 
76 version (CRuntime_Glibc)
77 {
78     // Some networking constants are subtly different for glibc, linux kernel
79     // constants are also provided below.
80 
81     //alias uint16_t in_port_t;
82     //alias uint32_t in_addr_t;
83 
84     //struct in_addr
85     //{
86     //    in_addr_t s_addr;
87     //}
88 
89     private enum __SOCK_SIZE__ = 16;
90 
91     struct sockaddr_in
92     {
93         sa_family_t sin_family;
94         in_port_t   sin_port;
95         in_addr     sin_addr;
96 
97         /* Pad to size of `struct sockaddr'. */
98         ubyte[__SOCK_SIZE__ - sa_family_t.sizeof -
99               in_port_t.sizeof - in_addr.sizeof] __pad;
100     }
101 
102     enum
103     {
104         IPPROTO_IP   = 0,
105         IPPROTO_ICMP = 1,
106         IPPROTO_IGMP = 2,
107         IPPROTO_GGP  = 3,
108         IPPROTO_TCP  = 6,
109         IPPROTO_PUP  = 12,
110         IPPROTO_UDP  = 17,
111         IPPROTO_IDP  = 22,
112         IPPROTO_ND   = 77,
113         IPPROTO_MAX  = 256
114     }
115 
116     enum : uint
117     {
118         INADDR_ANY       = 0x00000000,
119         INADDR_BROADCAST = 0xffffffff,
120         INADDR_LOOPBACK  = 0x7F000001,
121         INADDR_NONE      = 0xFFFFFFFF
122     }
123 
124     //enum INET_ADDRSTRLEN       = 16;
125 }
126 else version (Darwin)
127 {
128     //alias uint16_t in_port_t;
129     //alias uint32_t in_addr_t;
130 
131     //struct in_addr
132     //{
133     //    in_addr_t s_addr;
134     //}
135 
136     private enum __SOCK_SIZE__ = 16;
137 
138     struct sockaddr_in
139     {
140         ubyte       sin_len;
141         sa_family_t sin_family;
142         in_port_t   sin_port;
143         in_addr     sin_addr;
144         ubyte[8]    sin_zero;
145     }
146 
147     enum
148     {
149         IPPROTO_IP   = 0,
150         IPPROTO_ICMP = 1,
151         IPPROTO_IGMP = 2,
152         IPPROTO_GGP  = 3,
153         IPPROTO_TCP  = 6,
154         IPPROTO_PUP  = 12,
155         IPPROTO_UDP  = 17,
156         IPPROTO_IDP  = 22,
157         IPPROTO_ND   = 77,
158         IPPROTO_MAX  = 256
159     }
160 
161     enum : uint
162     {
163         INADDR_ANY       = 0x00000000,
164         INADDR_BROADCAST = 0xffffffff,
165         INADDR_LOOPBACK  = 0x7F000001,
166         INADDR_NONE      = 0xFFFFFFFF
167     }
168 
169     //enum INET_ADDRSTRLEN       = 16;
170 }
171 else version (FreeBSD)
172 {
173     //alias uint16_t in_port_t;
174     //alias uint32_t in_addr_t;
175 
176     //struct in_addr
177     //{
178     //    in_addr_t s_addr;
179     //}
180 
181     struct sockaddr_in
182     {
183         ubyte       sin_len;
184         sa_family_t sin_family;
185         in_port_t   sin_port;
186         in_addr     sin_addr;
187         ubyte[8]    sin_zero;
188     }
189 
190     enum
191     {
192         IPPROTO_IP   = 0,
193         IPPROTO_ICMP = 1,
194         IPPROTO_IGMP = 2,
195         IPPROTO_GGP  = 3,
196         IPPROTO_TCP  = 6,
197         IPPROTO_PUP  = 12,
198         IPPROTO_UDP  = 17,
199         IPPROTO_IDP  = 22,
200         IPPROTO_ND   = 77,
201         IPPROTO_MAX  = 256
202     }
203 
204     enum : uint
205     {
206         INADDR_ANY       = 0x00000000,
207         INADDR_BROADCAST = 0xffffffff,
208         INADDR_LOOPBACK  = 0x7f000001,
209         INADDR_NONE      = 0xffffffff
210     }
211 
212     //enum INET_ADDRSTRLEN       = 16;
213 }
214 else version (NetBSD)
215 {
216     struct sockaddr_in
217     {
218         ubyte       sin_len;
219         sa_family_t sin_family;
220         in_port_t   sin_port;
221         in_addr     sin_addr;
222         ubyte[8]    sin_zero;
223     }
224 
225     enum
226     {
227         IPPROTO_IP   = 0,
228         IPPROTO_ICMP = 1,
229         IPPROTO_IGMP = 2,
230         IPPROTO_GGP  = 3,
231         IPPROTO_TCP  = 6,
232         IPPROTO_PUP  = 12,
233         IPPROTO_UDP  = 17,
234         IPPROTO_IDP  = 22,
235         IPPROTO_ND   = 77,
236         IPPROTO_MAX  = 256
237     }
238 
239     enum : uint
240     {
241         INADDR_ANY       = 0x00000000,
242         INADDR_BROADCAST = 0xffffffff,
243         INADDR_LOOPBACK  = 0x7f000001,
244         INADDR_NONE      = 0xffffffff
245     }
246 
247     //enum INET_ADDRSTRLEN       = 16;
248 }
249 else version (OpenBSD)
250 {
251     struct sockaddr_in
252     {
253         ubyte       sin_len;
254         sa_family_t sin_family;
255         in_port_t   sin_port;
256         in_addr     sin_addr;
257         ubyte[8]    sin_zero;
258     }
259 
260     enum
261     {
262         IPPROTO_IP   = 0,
263         IPPROTO_ICMP = 1,
264         IPPROTO_IGMP = 2,
265         IPPROTO_GGP  = 3,
266         IPPROTO_TCP  = 6,
267         IPPROTO_PUP  = 12,
268         IPPROTO_UDP  = 17,
269         IPPROTO_IDP  = 22,
270         IPPROTO_MAX  = 256
271     }
272 
273     enum : uint
274     {
275         INADDR_ANY       = 0x00000000,
276         INADDR_BROADCAST = 0xffffffff,
277         INADDR_LOOPBACK  = 0x7f000001,
278         INADDR_NONE      = 0xffffffff
279     }
280 
281     enum INET_ADDRSTRLEN       = 16;
282 }
283 else version (DragonFlyBSD)
284 {
285     //alias uint16_t in_port_t;
286     //alias uint32_t in_addr_t;
287 
288     //struct in_addr
289     //{
290     //    in_addr_t s_addr;
291     //}
292 
293     struct sockaddr_in
294     {
295         ubyte       sin_len;
296         sa_family_t sin_family;
297         in_port_t   sin_port;
298         in_addr     sin_addr;
299         ubyte[8]    sin_zero;
300     }
301 
302     enum
303     {
304         IPPROTO_IP   = 0,
305         IPPROTO_ICMP = 1,
306         IPPROTO_IGMP = 2,
307         IPPROTO_GGP  = 3,
308         IPPROTO_TCP  = 6,
309         IPPROTO_PUP  = 12,
310         IPPROTO_UDP  = 17,
311         IPPROTO_IDP  = 22,
312         IPPROTO_ND   = 77,
313         IPPROTO_MAX  = 256
314     }
315 
316     enum : uint
317     {
318         INADDR_ANY       = 0x00000000,
319         INADDR_LOOPBACK  = 0x7f000001,
320         INADDR_BROADCAST = 0xffffffff,
321         INADDR_NONE      = 0xffffffff,
322     }
323 
324     //enum INET_ADDRSTRLEN       = 16;
325 }
326 else version (CRuntime_UClibc)
327 {
328     private enum __SOCK_SIZE__ = 16;
329 
330     struct sockaddr_in
331     {
332         sa_family_t sin_family;
333         in_port_t   sin_port;
334         in_addr     sin_addr;
335 
336         ubyte[__SOCK_SIZE__ - short.sizeof -
337               ushort.sizeof - in_addr.sizeof] __pad;
338     }
339 
340     enum
341     {
342         IPPROTO_IP      = 0,
343         IPPROTO_ICMP    = 1,
344         IPPROTO_IGMP    = 2,
345         IPPROTO_GGP     = 3,
346         IPPROTO_IPIP    = 4,
347         IPPROTO_TCP     = 6,
348         IPPROTO_EGP     = 8,
349         IPPROTO_PUP     = 12,
350         IPPROTO_UDP     = 17,
351         IPPROTO_IDP     = 22,
352         IPPROTO_TP      = 29,
353         IPPROTO_DCCP    = 33,
354         IPPROTO_RSVP    = 46,
355         IPPROTO_GRE     = 47,
356         IPPROTO_ESP     = 50,
357         IPPROTO_AH      = 51,
358         IPPROTO_MTP     = 92,
359         IPPROTO_BEETPH  = 94,
360         IPPROTO_ENCAP   = 98,
361         IPPROTO_PIM     = 103,
362         IPPROTO_COMP    = 108,
363         IPPROTO_SCTP    = 132,
364         IPPROTO_UDPLITE = 136,
365         IPPROTO_MPLS    = 137,
366         IPPROTO_MAX     = 256
367     }
368 
369     enum : uint
370     {
371         INADDR_ANY       = 0x00000000,
372         INADDR_BROADCAST = 0xffffffff,
373         IN_LOOPBACKNET   = 127,
374         INADDR_LOOPBACK  = 0x7F000001,
375         INADDR_NONE      = 0xFFFFFFFF
376     }
377 }
378 else version (Solaris)
379 {
380     struct sockaddr_in
381     {
382         sa_family_t sin_family;
383         in_port_t   sin_port;
384         in_addr     sin_addr;
385         ubyte[8]    sin_zero;
386     }
387 
388     enum
389     {
390         IPPROTO_IP   = 0,
391         IPPROTO_ICMP = 1,
392         IPPROTO_IGMP = 2,
393         IPPROTO_GGP  = 3,
394         IPPROTO_TCP  = 6,
395         IPPROTO_PUP  = 12,
396         IPPROTO_UDP  = 17,
397         IPPROTO_IDP  = 22,
398         IPPROTO_ND   = 77,
399         IPPROTO_MAX  = 256
400     }
401 
402     enum : uint
403     {
404         INADDR_ANY       = 0x00000000,
405         INADDR_BROADCAST = 0xffffffff,
406         INADDR_LOOPBACK  = 0x7f000001,
407         INADDR_NONE      = 0xffffffff
408     }
409 }
410 else version (linux)
411 {
412     private enum __SOCK_SIZE__ = 16;
413 
414     struct sockaddr_in
415     {
416         sa_family_t sin_family;
417         ushort      sin_port;
418         in_addr     sin_addr;
419 
420         /* Pad to size of `struct sockaddr'. */
421         ubyte[__SOCK_SIZE__ - sa_family_t.sizeof -
422               ushort.sizeof - in_addr.sizeof] __pad;
423     }
424 
425     enum
426     {
427         IPPROTO_IP   = 0,
428         IPPROTO_ICMP = 1,
429         IPPROTO_IGMP = 2,
430         IPPROTO_GGP  = 3,
431         IPPROTO_TCP  = 6,
432         IPPROTO_PUP  = 12,
433         IPPROTO_UDP  = 17,
434         IPPROTO_IDP  = 22
435     }
436 
437     enum : c_ulong
438     {
439         INADDR_ANY       = 0x00000000,
440         INADDR_BROADCAST = 0xffffffff,
441         INADDR_LOOPBACK  = 0x7f000001,
442         INADDR_NONE      = 0xFFFFFFFF
443     }
444 }
445 
446 
447 //
448 // IPV6 (IP6)
449 //
450 /*
451 NOTE: The following must must be defined in core.sys.posix.arpa.inet to break
452       a circular import: INET6_ADDRSTRLEN.
453 
454 struct in6_addr
455 {
456     uint8_t[16] s6_addr;
457 }
458 
459 struct sockaddr_in6
460 {
461     sa_family_t sin6_family;
462     in_port_t   sin6_port;
463     uint32_t    sin6_flowinfo;
464     in6_addr    sin6_addr;
465     uint32_t    sin6_scope_id;
466 }
467 
468 extern in6_addr in6addr_any;
469 extern in6_addr in6addr_loopback;
470 
471 struct ipv6_mreq
472 {
473     in6_addr    ipv6mr_multiaddr;
474     uint        ipv6mr_interface;
475 }
476 
477 IPPROTO_IPV6
478 
479 INET6_ADDRSTRLEN
480 
481 IPV6_JOIN_GROUP
482 IPV6_LEAVE_GROUP
483 IPV6_MULTICAST_HOPS
484 IPV6_MULTICAST_IF
485 IPV6_MULTICAST_LOOP
486 IPV6_UNICAST_HOPS
487 IPV6_V6ONLY
488 
489 // macros
490 int IN6_IS_ADDR_UNSPECIFIED(in6_addr*)
491 int IN6_IS_ADDR_LOOPBACK(in6_addr*)
492 int IN6_IS_ADDR_MULTICAST(in6_addr*)
493 int IN6_IS_ADDR_LINKLOCAL(in6_addr*)
494 int IN6_IS_ADDR_SITELOCAL(in6_addr*)
495 int IN6_IS_ADDR_V4MAPPED(in6_addr*)
496 int IN6_IS_ADDR_V4COMPAT(in6_addr*)
497 int IN6_IS_ADDR_MC_NODELOCAL(in6_addr*)
498 int IN6_IS_ADDR_MC_LINKLOCAL(in6_addr*)
499 int IN6_IS_ADDR_MC_SITELOCAL(in6_addr*)
500 int IN6_IS_ADDR_MC_ORGLOCAL(in6_addr*)
501 int IN6_IS_ADDR_MC_GLOBAL(in6_addr*)
502 */
503 
504 version (CRuntime_Glibc)
505 {
506     struct in6_addr
507     {
508         union
509         {
510             uint8_t[16] s6_addr;
511             uint16_t[8] s6_addr16;
512             uint32_t[4] s6_addr32;
513         }
514     }
515 
516     struct sockaddr_in6
517     {
518         sa_family_t sin6_family;
519         in_port_t   sin6_port;
520         uint32_t    sin6_flowinfo;
521         in6_addr    sin6_addr;
522         uint32_t    sin6_scope_id;
523     }
524 
525     extern __gshared immutable in6_addr in6addr_any;
526     extern __gshared immutable in6_addr in6addr_loopback;
527 
528     struct ipv6_mreq
529     {
530         in6_addr    ipv6mr_multiaddr;
531         uint        ipv6mr_interface;
532     }
533 
534     enum : uint
535     {
536         IPPROTO_IPV6        = 41,
537 
538         //INET6_ADDRSTRLEN    = 46,
539 
540         IPV6_JOIN_GROUP     = 20,
541         IPV6_LEAVE_GROUP    = 21,
542         IPV6_MULTICAST_HOPS = 18,
543         IPV6_MULTICAST_IF   = 17,
544         IPV6_MULTICAST_LOOP = 19,
545         IPV6_UNICAST_HOPS   = 16,
546         IPV6_V6ONLY         = 26
547     }
548 
549     // macros
550     extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* addr ) pure
551     {
552         return (cast(uint32_t*) addr)[0] == 0 &&
553                (cast(uint32_t*) addr)[1] == 0 &&
554                (cast(uint32_t*) addr)[2] == 0 &&
555                (cast(uint32_t*) addr)[3] == 0;
556     }
557 
558     extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* addr ) pure
559     {
560         return (cast(uint32_t*) addr)[0] == 0  &&
561                (cast(uint32_t*) addr)[1] == 0  &&
562                (cast(uint32_t*) addr)[2] == 0  &&
563                (cast(uint32_t*) addr)[3] == htonl( 1 );
564     }
565 
566     extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* addr ) pure
567     {
568         return (cast(uint8_t*) addr)[0] == 0xff;
569     }
570 
571     extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* addr ) pure
572     {
573         return ((cast(uint32_t*) addr)[0] & htonl( 0xffc00000 )) == htonl( 0xfe800000 );
574     }
575 
576     extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* addr ) pure
577     {
578         return ((cast(uint32_t*) addr)[0] & htonl( 0xffc00000 )) == htonl( 0xfec00000 );
579     }
580 
581     extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* addr ) pure
582     {
583         return (cast(uint32_t*) addr)[0] == 0 &&
584                (cast(uint32_t*) addr)[1] == 0 &&
585                (cast(uint32_t*) addr)[2] == htonl( 0xffff );
586     }
587 
588     extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* addr ) pure
589     {
590         return (cast(uint32_t*) addr)[0] == 0 &&
591                (cast(uint32_t*) addr)[1] == 0 &&
592                (cast(uint32_t*) addr)[2] == 0 &&
593                ntohl( (cast(uint32_t*) addr)[3] ) > 1;
594     }
595 
596     extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* addr ) pure
597     {
598         return IN6_IS_ADDR_MULTICAST( addr ) &&
599                ((cast(uint8_t*) addr)[1] & 0xf) == 0x1;
600     }
601 
602     extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* addr ) pure
603     {
604         return IN6_IS_ADDR_MULTICAST( addr ) &&
605                ((cast(uint8_t*) addr)[1] & 0xf) == 0x2;
606     }
607 
608     extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* addr ) pure
609     {
610         return IN6_IS_ADDR_MULTICAST(addr) &&
611                ((cast(uint8_t*) addr)[1] & 0xf) == 0x5;
612     }
613 
614     extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* addr ) pure
615     {
616         return IN6_IS_ADDR_MULTICAST( addr) &&
617                ((cast(uint8_t*) addr)[1] & 0xf) == 0x8;
618     }
619 
620     extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* addr ) pure
621     {
622         return IN6_IS_ADDR_MULTICAST( addr ) &&
623                ((cast(uint8_t*) addr)[1] & 0xf) == 0xe;
624     }
625 }
626 else version (Darwin)
627 {
628     struct in6_addr
629     {
630         union
631         {
632             uint8_t[16] s6_addr;
633             uint16_t[8] s6_addr16;
634             uint32_t[4] s6_addr32;
635         }
636     }
637 
638     struct sockaddr_in6
639     {
640         uint8_t     sin6_len;
641         sa_family_t sin6_family;
642         in_port_t   sin6_port;
643         uint32_t    sin6_flowinfo;
644         in6_addr    sin6_addr;
645         uint32_t    sin6_scope_id;
646     }
647 
648     extern __gshared immutable in6_addr in6addr_any;
649     extern __gshared immutable in6_addr in6addr_loopback;
650 
651     struct ipv6_mreq
652     {
653         in6_addr    ipv6mr_multiaddr;
654         uint        ipv6mr_interface;
655     }
656 
657     enum : uint
658     {
659         IPPROTO_IPV6        = 41,
660 
661         //INET6_ADDRSTRLEN    = 46,
662 
663         IPV6_JOIN_GROUP     = 12,
664         IPV6_LEAVE_GROUP    = 13,
665         IPV6_MULTICAST_HOPS = 10,
666         IPV6_MULTICAST_IF   = 9,
667         IPV6_MULTICAST_LOOP = 11,
668         IPV6_UNICAST_HOPS   = 4,
669         IPV6_V6ONLY         = 27
670     }
671 
672     // macros
673     extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* addr ) pure
674     {
675         return (cast(uint32_t*) addr)[0] == 0 &&
676                (cast(uint32_t*) addr)[1] == 0 &&
677                (cast(uint32_t*) addr)[2] == 0 &&
678                (cast(uint32_t*) addr)[3] == 0;
679     }
680 
681     extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* addr ) pure
682     {
683         return (cast(uint32_t*) addr)[0] == 0  &&
684                (cast(uint32_t*) addr)[1] == 0  &&
685                (cast(uint32_t*) addr)[2] == 0  &&
686                (cast(uint32_t*) addr)[3] == ntohl( 1 );
687     }
688 
689     extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* addr ) pure
690     {
691         return addr.s6_addr[0] == 0xff;
692     }
693 
694     extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* addr ) pure
695     {
696         return addr.s6_addr[0] == 0xfe && (addr.s6_addr[1] & 0xc0) == 0x80;
697     }
698 
699     extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* addr ) pure
700     {
701         return addr.s6_addr[0] == 0xfe && (addr.s6_addr[1] & 0xc0) == 0xc0;
702     }
703 
704     extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* addr ) pure
705     {
706         return (cast(uint32_t*) addr)[0] == 0 &&
707                (cast(uint32_t*) addr)[1] == 0 &&
708                (cast(uint32_t*) addr)[2] == ntohl( 0x0000ffff );
709     }
710 
711     extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* addr ) pure
712     {
713         return (cast(uint32_t*) addr)[0] == 0 &&
714                (cast(uint32_t*) addr)[1] == 0 &&
715                (cast(uint32_t*) addr)[2] == 0 &&
716                (cast(uint32_t*) addr)[3] != 0 &&
717                (cast(uint32_t*) addr)[3] != ntohl( 1 );
718     }
719 
720     extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* addr ) pure
721     {
722         return IN6_IS_ADDR_MULTICAST( addr ) &&
723                ((cast(uint8_t*) addr)[1] & 0xf) == 0x1;
724     }
725 
726     extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* addr ) pure
727     {
728         return IN6_IS_ADDR_MULTICAST( addr ) &&
729                ((cast(uint8_t*) addr)[1] & 0xf) == 0x2;
730     }
731 
732     extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* addr ) pure
733     {
734         return IN6_IS_ADDR_MULTICAST(addr) &&
735                ((cast(uint8_t*) addr)[1] & 0xf) == 0x5;
736     }
737 
738     extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* addr ) pure
739     {
740         return IN6_IS_ADDR_MULTICAST( addr) &&
741                ((cast(uint8_t*) addr)[1] & 0xf) == 0x8;
742     }
743 
744     extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* addr ) pure
745     {
746         return IN6_IS_ADDR_MULTICAST( addr ) &&
747                ((cast(uint8_t*) addr)[1] & 0xf) == 0xe;
748     }
749 }
750 else version (FreeBSD)
751 {
752     struct in6_addr
753     {
754         union
755         {
756             uint8_t[16] s6_addr;
757             uint16_t[8] s6_addr16;
758             uint32_t[4] s6_addr32;
759         }
760     }
761 
762     struct sockaddr_in6
763     {
764         uint8_t     sin6_len;
765         sa_family_t sin6_family;
766         in_port_t   sin6_port;
767         uint32_t    sin6_flowinfo;
768         in6_addr    sin6_addr;
769         uint32_t    sin6_scope_id;
770     }
771 
772     extern __gshared immutable in6_addr in6addr_any;
773     extern __gshared immutable in6_addr in6addr_loopback;
774 
775     struct ipv6_mreq
776     {
777         in6_addr    ipv6mr_multiaddr;
778         uint        ipv6mr_interface;
779     }
780 
781     enum : uint
782     {
783         IPPROTO_IPV6        = 41,
784 
785         //INET6_ADDRSTRLEN    = 46,
786 
787         IPV6_JOIN_GROUP     = 12,
788         IPV6_LEAVE_GROUP    = 13,
789         IPV6_MULTICAST_HOPS = 10,
790         IPV6_MULTICAST_IF   = 9,
791         IPV6_MULTICAST_LOOP = 11,
792         IPV6_UNICAST_HOPS   = 4,
793         IPV6_V6ONLY         = 27,
794     }
795 
796     private enum
797     {
798         __IPV6_ADDR_SCOPE_NODELOCAL     = 0x01,
799         __IPV6_ADDR_SCOPE_INTFACELOCAL  = 0x01,
800         __IPV6_ADDR_SCOPE_LINKLOCAL     = 0x02,
801         __IPV6_ADDR_SCOPE_SITELOCAL     = 0x05,
802         __IPV6_ADDR_SCOPE_ORGLOCAL      = 0x08,
803         __IPV6_ADDR_SCOPE_GLOBAL        = 0x0e,
804     }
805 
806     // macros
807     extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) pure
808     {
809         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
810                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
811                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&
812                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0);
813     }
814 
815     extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) pure
816     {
817         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
818                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
819                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&
820                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1));
821     }
822 
823     extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) pure
824     {
825         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
826                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
827                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&
828                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != 0) &&
829                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1));
830     }
831 
832     extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) pure
833     {
834         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
835                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
836                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff));
837     }
838 
839     extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) pure
840     {
841         return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80;
842     }
843 
844     extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) pure
845     {
846         return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0;
847     }
848 
849     extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) pure
850     {
851         return a.s6_addr[0] == 0xff;
852     }
853 
854     extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( const scope in6_addr* a ) pure
855     {
856         return a.s6_addr[1] & 0x0f;
857     }
858 
859     extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) pure
860     {
861         return IN6_IS_ADDR_MULTICAST(a) &&
862                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL;
863     }
864 
865     extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) pure
866     {
867         return IN6_IS_ADDR_MULTICAST(a) &&
868                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL;
869     }
870 
871     extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) pure
872     {
873         return IN6_IS_ADDR_MULTICAST(a) &&
874                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL;
875     }
876 
877     extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) pure
878     {
879         return IN6_IS_ADDR_MULTICAST(a) &&
880                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL;
881     }
882 
883     extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) pure
884     {
885         return IN6_IS_ADDR_MULTICAST(a) &&
886                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL;
887     }
888 }
889 else version (NetBSD)
890 {
891     struct in6_addr
892     {
893         union
894         {
895             uint8_t[16] s6_addr;
896             uint16_t[8] s6_addr16;
897             uint32_t[4] s6_addr32;
898         }
899     }
900 
901     struct sockaddr_in6
902     {
903         uint8_t     sin6_len;
904         sa_family_t sin6_family;
905         in_port_t   sin6_port;
906         uint32_t    sin6_flowinfo;
907         in6_addr    sin6_addr;
908         uint32_t    sin6_scope_id;
909     }
910 
911     extern __gshared immutable in6_addr in6addr_any;
912     extern __gshared immutable in6_addr in6addr_loopback;
913 
914     struct ipv6_mreq
915     {
916         in6_addr    ipv6mr_multiaddr;
917         uint        ipv6mr_interface;
918     }
919 
920     enum : uint
921     {
922         IPPROTO_IPV6        = 41,
923 
924         //INET6_ADDRSTRLEN    = 46,
925 
926         IPV6_JOIN_GROUP     = 12,
927         IPV6_LEAVE_GROUP    = 13,
928         IPV6_MULTICAST_HOPS = 10,
929         IPV6_MULTICAST_IF   = 9,
930         IPV6_MULTICAST_LOOP = 11,
931         IPV6_UNICAST_HOPS   = 4,
932         IPV6_V6ONLY         = 27,
933     }
934 
935     private enum
936     {
937         __IPV6_ADDR_SCOPE_NODELOCAL     = 0x01,
938         __IPV6_ADDR_SCOPE_INTFACELOCAL  = 0x01,
939         __IPV6_ADDR_SCOPE_LINKLOCAL     = 0x02,
940         __IPV6_ADDR_SCOPE_SITELOCAL     = 0x05,
941         __IPV6_ADDR_SCOPE_ORGLOCAL      = 0x08,
942         __IPV6_ADDR_SCOPE_GLOBAL        = 0x0e,
943     }
944 
945     // macros
946     extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) pure
947     {
948         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
949                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
950                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&
951                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0);
952     }
953 
954     extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) pure
955     {
956         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
957                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
958                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&
959                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1));
960     }
961 
962     extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) pure
963     {
964         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
965                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
966                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&
967                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != 0) &&
968                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1));
969     }
970 
971     extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) pure
972     {
973         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
974                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
975                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff));
976     }
977 
978     extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) pure
979     {
980         return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80;
981     }
982 
983     extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) pure
984     {
985         return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0;
986     }
987 
988     extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) pure
989     {
990         return a.s6_addr[0] == 0xff;
991     }
992 
993     extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( const scope in6_addr* a ) pure
994     {
995         return a.s6_addr[1] & 0x0f;
996     }
997 
998     extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) pure
999     {
1000         return IN6_IS_ADDR_MULTICAST(a) &&
1001                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL;
1002     }
1003 
1004     extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) pure
1005     {
1006         return IN6_IS_ADDR_MULTICAST(a) &&
1007                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL;
1008     }
1009 
1010     extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) pure
1011     {
1012         return IN6_IS_ADDR_MULTICAST(a) &&
1013                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL;
1014     }
1015 
1016     extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) pure
1017     {
1018         return IN6_IS_ADDR_MULTICAST(a) &&
1019                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL;
1020     }
1021 
1022     extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) pure
1023     {
1024         return IN6_IS_ADDR_MULTICAST(a) &&
1025                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL;
1026     }
1027 }
1028 else version (OpenBSD)
1029 {
1030     struct in6_addr
1031     {
1032         union
1033         {
1034             uint8_t[16] s6_addr;
1035             uint16_t[8] s6_addr16;
1036             uint32_t[4] s6_addr32;
1037         }
1038     }
1039 
1040     struct sockaddr_in6
1041     {
1042         uint8_t     sin6_len;
1043         sa_family_t sin6_family;
1044         in_port_t   sin6_port;
1045         uint32_t    sin6_flowinfo;
1046         in6_addr    sin6_addr;
1047         uint32_t    sin6_scope_id;
1048     }
1049 
1050     extern __gshared immutable in6_addr in6addr_any;
1051     extern __gshared immutable in6_addr in6addr_loopback;
1052 
1053     struct ipv6_mreq
1054     {
1055         in6_addr    ipv6mr_multiaddr;
1056         uint        ipv6mr_interface;
1057     }
1058 
1059     enum : uint
1060     {
1061         IPPROTO_IPV6        = 41,
1062 
1063         INET6_ADDRSTRLEN    = 46,
1064 
1065         IPV6_JOIN_GROUP     = 12,
1066         IPV6_LEAVE_GROUP    = 13,
1067         IPV6_MULTICAST_HOPS = 10,
1068         IPV6_MULTICAST_IF   = 9,
1069         IPV6_MULTICAST_LOOP = 11,
1070         IPV6_UNICAST_HOPS   = 4,
1071         IPV6_V6ONLY         = 27,
1072     }
1073 
1074     private enum
1075     {
1076         __IPV6_ADDR_SCOPE_NODELOCAL     = 0x01,
1077         __IPV6_ADDR_SCOPE_INTFACELOCAL  = 0x01,
1078         __IPV6_ADDR_SCOPE_LINKLOCAL     = 0x02,
1079         __IPV6_ADDR_SCOPE_SITELOCAL     = 0x05,
1080         __IPV6_ADDR_SCOPE_ORGLOCAL      = 0x08,
1081         __IPV6_ADDR_SCOPE_GLOBAL        = 0x0e,
1082     }
1083 
1084     // macros
1085     extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) pure
1086     {
1087         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
1088                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
1089                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&
1090                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0);
1091     }
1092 
1093     extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) pure
1094     {
1095         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
1096                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
1097                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&
1098                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1));
1099     }
1100 
1101     extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) pure
1102     {
1103         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
1104                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
1105                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&
1106                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != 0) &&
1107                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1));
1108     }
1109 
1110     extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) pure
1111     {
1112         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
1113                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
1114                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff));
1115     }
1116 
1117     extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) pure
1118     {
1119         return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80;
1120     }
1121 
1122     extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) pure
1123     {
1124         return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0;
1125     }
1126 
1127     extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) pure
1128     {
1129         return a.s6_addr[0] == 0xff;
1130     }
1131 
1132     extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( const scope in6_addr* a ) pure
1133     {
1134         return a.s6_addr[1] & 0x0f;
1135     }
1136 
1137     extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) pure
1138     {
1139         return IN6_IS_ADDR_MULTICAST(a) &&
1140                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL;
1141     }
1142 
1143     extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) pure
1144     {
1145         return IN6_IS_ADDR_MULTICAST(a) &&
1146                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL;
1147     }
1148 
1149     extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) pure
1150     {
1151         return IN6_IS_ADDR_MULTICAST(a) &&
1152                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL;
1153     }
1154 
1155     extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) pure
1156     {
1157         return IN6_IS_ADDR_MULTICAST(a) &&
1158                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL;
1159     }
1160 
1161     extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) pure
1162     {
1163         return IN6_IS_ADDR_MULTICAST(a) &&
1164                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL;
1165     }
1166 }
1167 else version (DragonFlyBSD)
1168 {
1169     struct in6_addr
1170     {
1171         union
1172         {
1173             uint8_t[16] s6_addr;
1174             uint16_t[8] s6_addr16;
1175             uint32_t[4] s6_addr32;
1176         }
1177     }
1178 
1179     struct sockaddr_in6
1180     {
1181         uint8_t     sin6_len;
1182         sa_family_t sin6_family;
1183         in_port_t   sin6_port;
1184         uint32_t    sin6_flowinfo;
1185         in6_addr    sin6_addr;
1186         uint32_t    sin6_scope_id;
1187     }
1188 
1189     extern __gshared immutable in6_addr in6addr_any;
1190     extern __gshared immutable in6_addr in6addr_loopback;
1191 
1192     struct ipv6_mreq
1193     {
1194         in6_addr    ipv6mr_multiaddr;
1195         uint        ipv6mr_interface;
1196     }
1197 
1198     enum : uint
1199     {
1200         IPPROTO_IPV6        = 41,
1201 
1202         //INET6_ADDRSTRLEN    = 46,
1203 
1204         IPV6_JOIN_GROUP     = 12,
1205         IPV6_LEAVE_GROUP    = 13,
1206         IPV6_MULTICAST_HOPS = 10,
1207         IPV6_MULTICAST_IF   = 9,
1208         IPV6_MULTICAST_LOOP = 11,
1209         IPV6_UNICAST_HOPS   = 4,
1210         IPV6_V6ONLY         = 27,
1211     }
1212 
1213     private enum
1214     {
1215         __IPV6_ADDR_SCOPE_NODELOCAL     = 0x01,
1216         __IPV6_ADDR_SCOPE_INTFACELOCAL  = 0x01,
1217         __IPV6_ADDR_SCOPE_LINKLOCAL     = 0x02,
1218         __IPV6_ADDR_SCOPE_SITELOCAL     = 0x05,
1219         __IPV6_ADDR_SCOPE_ORGLOCAL      = 0x08,
1220         __IPV6_ADDR_SCOPE_GLOBAL        = 0x0e,
1221     }
1222 
1223     // macros
1224     extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) pure
1225     {
1226         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
1227                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
1228                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&
1229                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0);
1230     }
1231 
1232     extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) pure
1233     {
1234         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
1235                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
1236                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&
1237                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1));
1238     }
1239 
1240     extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) pure
1241     {
1242         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
1243                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
1244                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&
1245                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != 0) &&
1246                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1));
1247     }
1248 
1249     extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) pure
1250     {
1251         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
1252                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
1253                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff));
1254     }
1255 
1256     extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) pure
1257     {
1258         return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80;
1259     }
1260 
1261     extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) pure
1262     {
1263         return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0;
1264     }
1265 
1266     extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) pure
1267     {
1268         return a.s6_addr[0] == 0xff;
1269     }
1270 
1271     extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( const scope in6_addr* a ) pure
1272     {
1273         return a.s6_addr[1] & 0x0f;
1274     }
1275 
1276     extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) pure
1277     {
1278         return IN6_IS_ADDR_MULTICAST(a) &&
1279                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL;
1280     }
1281 
1282     extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) pure
1283     {
1284         return IN6_IS_ADDR_MULTICAST(a) &&
1285                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL;
1286     }
1287 
1288     extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) pure
1289     {
1290         return IN6_IS_ADDR_MULTICAST(a) &&
1291                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL;
1292     }
1293 
1294     extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) pure
1295     {
1296         return IN6_IS_ADDR_MULTICAST(a) &&
1297                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL;
1298     }
1299 
1300     extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) pure
1301     {
1302         return IN6_IS_ADDR_MULTICAST(a) &&
1303                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL;
1304     }
1305 }
1306 else version (Solaris)
1307 {
1308     struct in6_addr
1309     {
1310         union
1311         {
1312             uint8_t[16] s6_addr;
1313             uint8_t[16] s6_addr8;
1314             uint32_t[4] s6_addr32;
1315         }
1316     }
1317 
1318     struct sockaddr_in6
1319     {
1320         sa_family_t sin6_family;
1321         in_port_t   sin6_port;
1322         uint32_t    sin6_flowinfo;
1323         in6_addr    sin6_addr;
1324         uint32_t    sin6_scope_id;
1325         uint32_t    __sin6_src_id;
1326     }
1327 
1328     extern __gshared immutable in6_addr in6addr_any;
1329     extern __gshared immutable in6_addr in6addr_loopback;
1330 
1331     struct ipv6_mreq
1332     {
1333         in6_addr    ipv6mr_multiaddr;
1334         uint        ipv6mr_interface;
1335     }
1336 
1337     enum : uint
1338     {
1339         IPPROTO_IPV6        = 41,
1340 
1341         //INET6_ADDRSTRLEN    = 46,
1342 
1343         IPV6_JOIN_GROUP     = 9,
1344         IPV6_LEAVE_GROUP    = 10,
1345         IPV6_MULTICAST_HOPS = 7,
1346         IPV6_MULTICAST_IF   = 6,
1347         IPV6_MULTICAST_LOOP = 8,
1348         IPV6_UNICAST_HOPS   = 5,
1349         IPV6_V6ONLY         = 39,
1350     }
1351 
1352     // macros
1353     extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) pure
1354     {
1355         return (a.s6_addr32[0] == 0) && (a.s6_addr32[1] == 0) &&
1356                (a.s6_addr32[2] == 0) && (a.s6_addr32[3] == 0);
1357     }
1358 
1359     extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) pure
1360     {
1361         return (a.s6_addr32[0] == 0) && (a.s6_addr32[1] == 0) &&
1362                (a.s6_addr32[2] == 0) && (a.s6_addr32[3] == ntohl(1));
1363     }
1364 
1365     extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) pure
1366     {
1367         return (a.s6_addr32[0] == 0) && (a.s6_addr32[1] == 0) &&
1368                (a.s6_addr32[2] == 0) && (a.s6_addr32[3] != 0) &&
1369                (a.s6_addr32[3] != ntohl(1));
1370     }
1371 
1372     extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) pure
1373     {
1374         return (a.s6_addr32[0] == 0) && (a.s6_addr32[1] == 0) &&
1375                (a.s6_addr32[2] == ntohl(0x0000ffff));
1376     }
1377 
1378     extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) pure
1379     {
1380         return a.s6_addr8[0] == 0xfe && (a.s6_addr8[1] & 0xc0) == 0x80;
1381     }
1382 
1383     extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) pure
1384     {
1385         return a.s6_addr8[0] == 0xfe && (a.s6_addr8[1] & 0xc0) == 0xc0;
1386     }
1387 
1388     extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) pure
1389     {
1390         return a.s6_addr8[0] == 0xff;
1391     }
1392 
1393     extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) pure
1394     {
1395         return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x01;
1396     }
1397 
1398     extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) pure
1399     {
1400         return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x02;
1401     }
1402 
1403     extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) pure
1404     {
1405         return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x05;
1406     }
1407 
1408     extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) pure
1409     {
1410         return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x08;
1411     }
1412 
1413     extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) pure
1414     {
1415         return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x0e;
1416     }
1417 }
1418 else version (CRuntime_Bionic)
1419 {
1420     struct in6_addr
1421     {
1422         union
1423         {
1424             uint8_t[16] s6_addr;
1425             uint16_t[8] s6_addr16;
1426             uint32_t[4] s6_addr32;
1427         }
1428     }
1429 
1430     struct sockaddr_in6
1431     {
1432         ushort      sin6_family;
1433         uint16_t    sin6_port;
1434         uint32_t    sin6_flowinfo;
1435         in6_addr    sin6_addr;
1436         uint32_t    sin6_scope_id;
1437     }
1438 
1439     __gshared immutable in6_addr in6addr_any = {[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]};
1440     __gshared immutable in6_addr in6addr_loopback = {[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]};
1441 
1442     struct ipv6_mreq
1443     {
1444         in6_addr ipv6mr_multiaddr;
1445         int      ipv6mr_ifindex;
1446     }
1447 
1448     enum : uint
1449     {
1450         IPPROTO_IPV6        = 41,
1451 
1452         IPV6_JOIN_GROUP     = 20,
1453         IPV6_LEAVE_GROUP    = 21,
1454         IPV6_MULTICAST_HOPS = 18,
1455         IPV6_MULTICAST_IF   = 17,
1456         IPV6_MULTICAST_LOOP = 19,
1457         IPV6_UNICAST_HOPS   = 16,
1458         IPV6_V6ONLY         = 26
1459     }
1460 
1461     private enum
1462     {
1463         IPV6_ADDR_SCOPE_NODELOCAL     = 0x01,
1464         IPV6_ADDR_SCOPE_INTFACELOCAL  = 0x01,
1465         IPV6_ADDR_SCOPE_LINKLOCAL     = 0x02,
1466         IPV6_ADDR_SCOPE_SITELOCAL     = 0x05,
1467         IPV6_ADDR_SCOPE_ORGLOCAL      = 0x08,
1468         IPV6_ADDR_SCOPE_GLOBAL        = 0x0e,
1469     }
1470 
1471     extern (D) pure
1472     {
1473         bool IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a )
1474         {
1475             return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
1476                    (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
1477                    (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&
1478                    (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0);
1479         }
1480 
1481         bool IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a )
1482         {
1483             return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
1484                    (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
1485                    (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&
1486                    (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1));
1487         }
1488 
1489         bool IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a )
1490         {
1491             return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
1492                    (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
1493                    (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&
1494                    (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != 0) &&
1495                    (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1));
1496         }
1497 
1498         bool IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a )
1499         {
1500             return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
1501                    (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
1502                    (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff));
1503         }
1504 
1505         bool IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a )
1506         {
1507             return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80;
1508         }
1509 
1510         bool IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a )
1511         {
1512             return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0;
1513         }
1514 
1515         bool IN6_IS_ADDR_ULA( const scope in6_addr* a )
1516         {
1517             return (a.s6_addr[0] & 0xfe) == 0xfc;
1518         }
1519 
1520         bool IN6_IS_ADDR_MULTICAST( const scope in6_addr* a )
1521         {
1522             return a.s6_addr[0] == 0xff;
1523         }
1524 
1525         uint8_t IPV6_ADDR_MC_SCOPE( const scope in6_addr* a )
1526         {
1527             return a.s6_addr[1] & 0x0f;
1528         }
1529 
1530         bool IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a )
1531         {
1532             return IN6_IS_ADDR_MULTICAST(a) &&
1533                    IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_NODELOCAL;
1534         }
1535 
1536         bool IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a )
1537         {
1538             return IN6_IS_ADDR_MULTICAST(a) &&
1539                    IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_LINKLOCAL;
1540         }
1541 
1542         bool IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a )
1543         {
1544             return IN6_IS_ADDR_MULTICAST(a) &&
1545                    IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_SITELOCAL;
1546         }
1547 
1548         bool IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a )
1549         {
1550             return IN6_IS_ADDR_MULTICAST(a) &&
1551                    IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_ORGLOCAL;
1552         }
1553 
1554         bool IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a )
1555         {
1556             return IN6_IS_ADDR_MULTICAST(a) &&
1557                    IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_GLOBAL;
1558         }
1559     }
1560 }
1561 else version (CRuntime_Musl)
1562 {
1563 
1564     struct in6_addr {
1565         union {
1566             uint8_t[16] s6_addr;
1567             uint16_t[8] s6_addr16;
1568             uint32_t[4] s6_addr32;
1569         }
1570     }
1571     struct sockaddr_in6 {
1572         sa_family_t     sin6_family;
1573         in_port_t       sin6_port;
1574         uint32_t        sin6_flowinfo;
1575         in6_addr        sin6_addr;
1576         uint32_t        sin6_scope_id;
1577     }
1578 
1579     struct ipv6_mreq
1580     {
1581         in6_addr    ipv6mr_multiaddr;
1582         uint        ipv6mr_interface;
1583     }
1584 
1585     enum : uint
1586     {
1587         IPPROTO_IPV6 = 41,
1588 
1589         IPV6_UNICAST_HOPS   = 16,
1590         IPV6_MULTICAST_IF   = 17,
1591         IPV6_MULTICAST_HOPS = 18,
1592         IPV6_MULTICAST_LOOP = 19,
1593         IPV6_JOIN_GROUP     = 20,
1594         IPV6_LEAVE_GROUP    = 21,
1595         IPV6_V6ONLY         = 26
1596     }
1597     extern __gshared immutable in6_addr in6addr_any;
1598     extern __gshared immutable in6_addr in6addr_loopback;
1599 }
1600 else version (CRuntime_UClibc)
1601 {
1602     struct in6_addr
1603     {
1604         union
1605         {
1606             uint8_t[16] s6_addr;
1607             uint16_t[8] s6_addr16;
1608             uint32_t[4] s6_addr32;
1609         }
1610     }
1611 
1612     struct sockaddr_in6
1613     {
1614         sa_family_t sin6_family;
1615         in_port_t   sin6_port;
1616         uint32_t    sin6_flowinfo;
1617         in6_addr    sin6_addr;
1618         uint32_t    sin6_scope_id;
1619     }
1620 
1621     extern __gshared immutable in6_addr in6addr_any;
1622     extern __gshared immutable in6_addr in6addr_loopback;
1623 
1624     struct ipv6_mreq
1625     {
1626         in6_addr    ipv6mr_multiaddr;
1627         uint        ipv6mr_interface;
1628     }
1629 
1630     enum : uint
1631     {
1632         IPPROTO_IPV6        = 41,
1633         IPV6_JOIN_GROUP     = 20,
1634         IPV6_LEAVE_GROUP    = 21,
1635         IPV6_MULTICAST_HOPS = 18,
1636         IPV6_MULTICAST_IF   = 17,
1637         IPV6_MULTICAST_LOOP = 19,
1638         IPV6_UNICAST_HOPS   = 16,
1639         IPV6_V6ONLY         = 26
1640     }
1641 
1642     // macros
1643     extern (D) int IN6_IS_ADDR_UNSPECIFIED( in6_addr* addr ) pure
1644     {
1645         return (cast(uint32_t*) addr)[0] == 0 &&
1646                (cast(uint32_t*) addr)[1] == 0 &&
1647                (cast(uint32_t*) addr)[2] == 0 &&
1648                (cast(uint32_t*) addr)[3] == 0;
1649     }
1650 
1651     extern (D) int IN6_IS_ADDR_LOOPBACK( in6_addr* addr ) pure
1652     {
1653         return (cast(uint32_t*) addr)[0] == 0  &&
1654                (cast(uint32_t*) addr)[1] == 0  &&
1655                (cast(uint32_t*) addr)[2] == 0  &&
1656                (cast(uint32_t*) addr)[3] == htonl( 1 );
1657     }
1658 
1659     extern (D) int IN6_IS_ADDR_MULTICAST( in6_addr* addr ) pure
1660     {
1661         return (cast(uint8_t*) addr)[0] == 0xff;
1662     }
1663 
1664     extern (D) int IN6_IS_ADDR_LINKLOCAL( in6_addr* addr ) pure
1665     {
1666         return ((cast(uint32_t*) addr)[0] & htonl( 0xffc00000 )) == htonl( 0xfe800000 );
1667     }
1668 
1669     extern (D) int IN6_IS_ADDR_SITELOCAL( in6_addr* addr ) pure
1670     {
1671         return ((cast(uint32_t*) addr)[0] & htonl( 0xffc00000 )) == htonl( 0xfec00000 );
1672     }
1673 
1674     extern (D) int IN6_IS_ADDR_V4MAPPED( in6_addr* addr ) pure
1675     {
1676         return (cast(uint32_t*) addr)[0] == 0 &&
1677                (cast(uint32_t*) addr)[1] == 0 &&
1678                (cast(uint32_t*) addr)[2] == htonl( 0xffff );
1679     }
1680 
1681     extern (D) int IN6_IS_ADDR_V4COMPAT( in6_addr* addr ) pure
1682     {
1683         return (cast(uint32_t*) addr)[0] == 0 &&
1684                (cast(uint32_t*) addr)[1] == 0 &&
1685                (cast(uint32_t*) addr)[2] == 0 &&
1686                ntohl( (cast(uint32_t*) addr)[3] ) > 1;
1687     }
1688 
1689     extern (D) int IN6_ARE_ADDR_EQUAL( in6_addr* a, in6_addr* b ) pure
1690     {
1691         return (cast(uint32_t*) a)[0] == (cast(uint32_t*) b)[0] &&
1692                (cast(uint32_t*) a)[1] == (cast(uint32_t*) b)[1] &&
1693                (cast(uint32_t*) a)[2] == (cast(uint32_t*) b)[2] &&
1694                (cast(uint32_t*) a)[3] == (cast(uint32_t*) b)[3];
1695     }
1696 
1697     extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in6_addr* addr ) pure
1698     {
1699         return IN6_IS_ADDR_MULTICAST( addr ) &&
1700                ((cast(uint8_t*) addr)[1] & 0xf) == 0x1;
1701     }
1702 
1703     extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in6_addr* addr ) pure
1704     {
1705         return IN6_IS_ADDR_MULTICAST( addr ) &&
1706                ((cast(uint8_t*) addr)[1] & 0xf) == 0x2;
1707     }
1708 
1709     extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in6_addr* addr ) pure
1710     {
1711         return IN6_IS_ADDR_MULTICAST(addr) &&
1712                ((cast(uint8_t*) addr)[1] & 0xf) == 0x5;
1713     }
1714 
1715     extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in6_addr* addr ) pure
1716     {
1717         return IN6_IS_ADDR_MULTICAST( addr) &&
1718                ((cast(uint8_t*) addr)[1] & 0xf) == 0x8;
1719     }
1720 
1721     extern (D) int IN6_IS_ADDR_MC_GLOBAL( in6_addr* addr ) pure
1722     {
1723         return IN6_IS_ADDR_MULTICAST( addr ) &&
1724                ((cast(uint8_t*) addr)[1] & 0xf) == 0xe;
1725     }
1726 }
1727 
1728 
1729 //
1730 // Raw Sockets (RS)
1731 //
1732 /*
1733 IPPROTO_RAW
1734 */
1735 
1736 version (CRuntime_Glibc)
1737 {
1738     enum uint IPPROTO_RAW = 255;
1739 }
1740 else version (Darwin)
1741 {
1742     enum uint IPPROTO_RAW = 255;
1743 }
1744 else version (FreeBSD)
1745 {
1746     enum uint IPPROTO_RAW = 255;
1747 }
1748 else version (NetBSD)
1749 {
1750     enum uint IPPROTO_RAW = 255;
1751 }
1752 else version (OpenBSD)
1753 {
1754     enum uint IPPROTO_RAW = 255;
1755 }
1756 else version (DragonFlyBSD)
1757 {
1758     enum uint IPPROTO_RAW = 255;
1759 }
1760 else version (Solaris)
1761 {
1762     enum uint IPPROTO_RAW = 255;
1763 }
1764 else version (linux)
1765 {
1766     enum uint IPPROTO_RAW = 255;
1767 }
1768 else version (CRuntime_UClibc)
1769 {
1770     enum uint IPPROTO_RAW = 255;
1771 }