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
version(Posix)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( 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( 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( in6_addr* addr ) pure
567 {
568 return (cast(uint8_t*) addr)[0] == 0xff;
569 }
570
571 extern (D) int IN6_IS_ADDR_LINKLOCAL( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( in6_addr* addr ) pure
690 {
691 return addr.s6_addr[0] == 0xff;
692 }
693
694 extern (D) int IN6_IS_ADDR_LINKLOCAL( 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( 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( 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( 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( 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( 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( 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( 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( 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 }
1772