1 /** 2 * D header file for POSIX. 3 * 4 * Copyright: Public Domain 5 * License: Public Domain 6 * Authors: Sean Kelly 7 * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition 8 */ 9 module tango.stdc.posix.netinet.in_; 10 11 private import tango.stdc.posix.config; 12 public import tango.stdc.inttypes : uint32_t, uint16_t, uint8_t; 13 public import tango.stdc.posix.arpa.inet; 14 public import tango.stdc.posix.sys.socket; // for sa_family_t 15 16 extern (C): 17 18 // 19 // Required 20 // 21 /* 22 NOTE: The following must must be defined in tango.stdc.posix.arpa.inet to break 23 a circular import: in_port_t, in_addr_t, struct in_addr, INET_ADDRSTRLEN. 24 25 in_port_t 26 in_addr_t 27 28 sa_family_t // from tango.stdc.posix.sys.socket 29 uint8_t // from tango.stdc.inttypes 30 uint32_t // from tango.stdc.inttypes 31 32 struct in_addr 33 { 34 in_addr_t s_addr; 35 } 36 37 struct sockaddr_in 38 { 39 sa_family_t sin_family; 40 in_port_t sin_port; 41 in_addr sin_addr; 42 } 43 44 IPPROTO_IP 45 IPPROTO_ICMP 46 IPPROTO_TCP 47 IPPROTO_UDP 48 49 INADDR_ANY 50 INADDR_BROADCAST 51 52 INET_ADDRSTRLEN 53 54 htonl() // from tango.stdc.posix.arpa.inet 55 htons() // from tango.stdc.posix.arpa.inet 56 ntohl() // from tango.stdc.posix.arpa.inet 57 ntohs() // from tango.stdc.posix.arpa.inet 58 */ 59 60 version( linux ) 61 { 62 private const __SOCK_SIZE__ = 16; 63 64 struct sockaddr_in 65 { 66 sa_family_t sin_family; 67 in_port_t sin_port; 68 in_addr sin_addr; 69 70 /* Pad to size of `struct sockaddr'. */ 71 ubyte[__SOCK_SIZE__ - sa_family_t.sizeof - 72 in_port_t.sizeof - in_addr.sizeof] __pad; 73 } 74 75 enum 76 { 77 IPPROTO_IP = 0, 78 IPPROTO_ICMP = 1, 79 IPPROTO_TCP = 6, 80 IPPROTO_UDP = 17 81 } 82 83 const uint INADDR_ANY = 0x00000000; 84 const uint INADDR_BROADCAST = 0xffffffff; 85 } 86 else version(OSX) 87 { 88 private const __SOCK_SIZE__ = 16; 89 90 struct sockaddr_in 91 { 92 ubyte sin_len; 93 sa_family_t sin_family; 94 in_port_t sin_port; 95 in_addr sin_addr; 96 ubyte[8] sin_zero; 97 } 98 99 enum 100 { 101 IPPROTO_IP = 0, 102 IPPROTO_ICMP = 1, 103 IPPROTO_TCP = 6, 104 IPPROTO_UDP = 17 105 } 106 107 const uint INADDR_ANY = 0x00000000; 108 const uint INADDR_BROADCAST = 0xffffffff; 109 } 110 else version( FreeBSD ) 111 { 112 private const __SOCK_SIZE__ = 16; 113 114 struct sockaddr_in 115 { 116 ubyte sin_len; 117 sa_family_t sin_family; 118 in_port_t sin_port; 119 in_addr sin_addr; 120 ubyte[8] sin_zero; 121 } 122 123 enum 124 { 125 IPPROTO_IP = 0, 126 IPPROTO_ICMP = 1, 127 IPPROTO_TCP = 6, 128 IPPROTO_UDP = 17 129 } 130 131 const uint INADDR_ANY = 0x00000000; 132 const uint INADDR_BROADCAST = 0xffffffff; 133 } 134 else version( solaris ) 135 { 136 struct sockaddr_in 137 { 138 sa_family_t sin_family; 139 in_port_t sin_port; 140 in_addr sin_addr; 141 ubyte[8] sin_zero; 142 } 143 144 enum 145 { 146 IPPROTO_IP = 0, 147 IPPROTO_ICMP = 1, 148 IPPROTO_TCP = 6, 149 IPPROTO_UDP = 17 150 } 151 152 const uint INADDR_ANY = 0x00000000; 153 const uint INADDR_BROADCAST = 0xffffffff; 154 } 155 156 157 // 158 // IPV6 (IP6) 159 // 160 /* 161 NOTE: The following must must be defined in tango.stdc.posix.arpa.inet to break 162 a circular import: INET6_ADDRSTRLEN. 163 164 struct in6_addr 165 { 166 uint8_t[16] s6_addr; 167 } 168 169 struct sockaddr_in6 170 { 171 sa_family_t sin6_family; 172 in_port_t sin6_port; 173 uint32_t sin6_flowinfo; 174 in6_addr sin6_addr; 175 uint32_t sin6_scope_id; 176 } 177 178 extern in6_addr in6addr_any; 179 extern in6_addr in6addr_loopback; 180 181 struct ipv6_mreq 182 { 183 in6_addr ipv6mr_multiaddr; 184 uint ipv6mr_interface; 185 } 186 187 IPPROTO_IPV6 188 189 INET6_ADDRSTRLEN 190 191 IPV6_JOIN_GROUP 192 IPV6_LEAVE_GROUP 193 IPV6_MULTICAST_HOPS 194 IPV6_MULTICAST_IF 195 IPV6_MULTICAST_LOOP 196 IPV6_UNICAST_HOPS 197 IPV6_V6ONLY 198 199 // macros 200 int IN6_IS_ADDR_UNSPECIFIED(in6_addr*) 201 int IN6_IS_ADDR_LOOPBACK(in6_addr*) 202 int IN6_IS_ADDR_MULTICAST(in6_addr*) 203 int IN6_IS_ADDR_LINKLOCAL(in6_addr*) 204 int IN6_IS_ADDR_SITELOCAL(in6_addr*) 205 int IN6_IS_ADDR_V4MAPPED(in6_addr*) 206 int IN6_IS_ADDR_V4COMPAT(in6_addr*) 207 int IN6_IS_ADDR_MC_NODELOCAL(in6_addr*) 208 int IN6_IS_ADDR_MC_LINKLOCAL(in6_addr*) 209 int IN6_IS_ADDR_MC_SITELOCAL(in6_addr*) 210 int IN6_IS_ADDR_MC_ORGLOCAL(in6_addr*) 211 int IN6_IS_ADDR_MC_GLOBAL(in6_addr*) 212 */ 213 214 version ( linux ) 215 { 216 struct in6_addr 217 { 218 union 219 { 220 uint8_t[16] s6_addr; 221 uint16_t[8] s6_addr16; 222 uint32_t[4] s6_addr32; 223 } 224 } 225 226 struct sockaddr_in6 227 { 228 sa_family_t sin6_family; 229 in_port_t sin6_port; 230 uint32_t sin6_flowinfo; 231 in6_addr sin6_addr; 232 uint32_t sin6_scope_id; 233 } 234 235 extern in6_addr in6addr_any; 236 extern in6_addr in6addr_loopback; 237 238 struct ipv6_mreq 239 { 240 in6_addr ipv6mr_multiaddr; 241 uint ipv6mr_interface; 242 } 243 244 enum : uint 245 { 246 IPPROTO_IPV6 = 41, 247 248 INET6_ADDRSTRLEN = 46, 249 250 IPV6_JOIN_GROUP = 20, 251 IPV6_LEAVE_GROUP = 21, 252 IPV6_MULTICAST_HOPS = 18, 253 IPV6_MULTICAST_IF = 17, 254 IPV6_MULTICAST_LOOP = 19, 255 IPV6_UNICAST_HOPS = 16, 256 IPV6_V6ONLY = 26 257 } 258 259 // macros 260 extern (D) int IN6_IS_ADDR_UNSPECIFIED( in6_addr* addr ) 261 { 262 return (cast(uint32_t*) addr)[0] == 0 && 263 (cast(uint32_t*) addr)[1] == 0 && 264 (cast(uint32_t*) addr)[2] == 0 && 265 (cast(uint32_t*) addr)[3] == 0; 266 } 267 268 extern (D) int IN6_IS_ADDR_LOOPBACK( in6_addr* addr ) 269 { 270 return (cast(uint32_t*) addr)[0] == 0 && 271 (cast(uint32_t*) addr)[1] == 0 && 272 (cast(uint32_t*) addr)[2] == 0 && 273 (cast(uint32_t*) addr)[3] == htonl( 1 ); 274 } 275 276 extern (D) int IN6_IS_ADDR_MULTICAST( in6_addr* addr ) 277 { 278 return (cast(uint8_t*) addr)[0] == 0xff; 279 } 280 281 extern (D) int IN6_IS_ADDR_LINKLOCAL( in6_addr* addr ) 282 { 283 return ((cast(uint32_t*) addr)[0] & htonl( 0xffc00000 )) == htonl( 0xfe800000 ); 284 } 285 286 extern (D) int IN6_IS_ADDR_SITELOCAL( in6_addr* addr ) 287 { 288 return ((cast(uint32_t*) addr)[0] & htonl( 0xffc00000 )) == htonl( 0xfec00000 ); 289 } 290 291 extern (D) int IN6_IS_ADDR_V4MAPPED( in6_addr* addr ) 292 { 293 return (cast(uint32_t*) addr)[0] == 0 && 294 (cast(uint32_t*) addr)[1] == 0 && 295 (cast(uint32_t*) addr)[2] == htonl( 0xffff ); 296 } 297 298 extern (D) int IN6_IS_ADDR_V4COMPAT( in6_addr* addr ) 299 { 300 return (cast(uint32_t*) addr)[0] == 0 && 301 (cast(uint32_t*) addr)[1] == 0 && 302 (cast(uint32_t*) addr)[2] == 0 && 303 ntohl( (cast(uint32_t*) addr)[3] ) > 1; 304 } 305 306 extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in6_addr* addr ) 307 { 308 return IN6_IS_ADDR_MULTICAST( addr ) && 309 ((cast(uint8_t*) addr)[1] & 0xf) == 0x1; 310 } 311 312 extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in6_addr* addr ) 313 { 314 return IN6_IS_ADDR_MULTICAST( addr ) && 315 ((cast(uint8_t*) addr)[1] & 0xf) == 0x2; 316 } 317 318 extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in6_addr* addr ) 319 { 320 return IN6_IS_ADDR_MULTICAST(addr) && 321 ((cast(uint8_t*) addr)[1] & 0xf) == 0x5; 322 } 323 324 extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in6_addr* addr ) 325 { 326 return IN6_IS_ADDR_MULTICAST( addr) && 327 ((cast(uint8_t*) addr)[1] & 0xf) == 0x8; 328 } 329 330 extern (D) int IN6_IS_ADDR_MC_GLOBAL( in6_addr* addr ) 331 { 332 return IN6_IS_ADDR_MULTICAST( addr ) && 333 ((cast(uint8_t*) addr)[1] & 0xf) == 0xe; 334 } 335 } 336 version ( solaris ) 337 { 338 struct in6_addr 339 { 340 union 341 { 342 uint8_t[16] s6_addr; 343 uint32_t[4] s6_addr32; 344 uint32_t __S6_align; 345 } 346 } 347 348 struct sockaddr_in6 349 { 350 sa_family_t sin6_family; 351 in_port_t sin6_port; 352 uint32_t sin6_flowinfo; 353 in6_addr sin6_addr; 354 uint32_t sin6_scope_id; 355 uint32_t __sin6_src_id; /* Impl. specific - UDP replies */ 356 } 357 358 extern in6_addr in6addr_any; 359 extern in6_addr in6addr_loopback; 360 361 struct ipv6_mreq 362 { 363 in6_addr ipv6mr_multiaddr; 364 uint ipv6mr_interface; 365 } 366 367 enum : uint 368 { 369 IPPROTO_IPV6 = 41, 370 371 INET6_ADDRSTRLEN = 46, 372 373 IPV6_JOIN_GROUP = 0x9, 374 IPV6_LEAVE_GROUP = 0xa, 375 IPV6_MULTICAST_HOPS = 0x7, 376 IPV6_MULTICAST_IF = 0x6, 377 IPV6_MULTICAST_LOOP = 0x8, 378 IPV6_UNICAST_HOPS = 0x5, 379 IPV6_V6ONLY = 0x27 380 } 381 382 // macros 383 extern (D) int IN6_IS_ADDR_UNSPECIFIED( in6_addr* addr ) 384 { 385 return addr.s6_addr32[3] == 0 && 386 addr.s6_addr32[2] == 0 && 387 addr.s6_addr32[1] == 0 && 388 addr.s6_addr32[0] == 0; 389 } 390 391 version(BigEndian) 392 { 393 extern (D) int IN6_IS_ADDR_LOOPBACK( in6_addr* addr ) 394 { 395 version(BigEndian) enum : uint { N = 0x00000001 } 396 else enum : uint { N = 0x01000000 } 397 398 return addr.s6_addr32[3] == N && 399 addr.s6_addr32[2] == 0 && 400 addr.s6_addr32[1] == 0 && 401 addr.s6_addr32[0] == 0; 402 } 403 } 404 405 // 406 // Note to tango devs: 407 // These macros seem alot more efficient then the Linux ones! 408 // 409 410 extern (D) int IN6_IS_ADDR_MULTICAST( in6_addr* addr ) 411 { 412 version(BigEndian) 413 return (addr.s6_addr32[0] & 0xff000000) == 0xff000000; 414 else 415 return (addr.s6_addr32[0] & 0x000000ff) == 0x000000ff; 416 } 417 418 extern (D) int IN6_IS_ADDR_LINKLOCAL( in6_addr* addr ) 419 { 420 version(BigEndian) 421 return (addr.s6_addr32[0] & 0xffc00000) == 0xfe800000; 422 else 423 return (addr.s6_addr32[0] & 0x0000c0ff) == 0x000080fe; 424 } 425 426 extern (D) int IN6_IS_ADDR_SITELOCAL( in6_addr* addr ) 427 { 428 version(BigEndian) 429 return (addr.s6_addr32[0] & 0xffc00000) == 0xfec00000; 430 else 431 return (addr.s6_addr32[0] & 0x0000c0ff) == 0x0000c0fe; 432 } 433 434 extern (D) int IN6_IS_ADDR_V4MAPPED( in6_addr* addr ) 435 { 436 version(BigEndian) enum : uint { N = 0x0000ffff } 437 else enum : uint { N = 0xffff0000 } 438 439 return addr.s6_addr32[2] == N && 440 addr.s6_addr32[1] == 0 && 441 addr.s6_addr32[0] == 0; 442 } 443 444 extern (D) int IN6_IS_ADDR_V4COMPAT( in6_addr* addr ) 445 { 446 version(BigEndian) enum : uint { N = 0x00000001 } 447 else enum : uint { N = 0x01000000 } 448 449 return addr.s6_addr32[2] == 0 && 450 addr.s6_addr32[1] == 0 && 451 addr.s6_addr32[0] == 0 && 452 addr.s6_addr32[3] != 0 && 453 addr.s6_addr32[3] != N; 454 } 455 456 extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in6_addr* addr ) 457 { 458 version(BigEndian) 459 return (addr.s6_addr32[0] & 0xff0f0000) == 0xff010000; 460 else 461 return (addr.s6_addr32[0] & 0x00000fff) == 0x000001ff; 462 } 463 464 extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in6_addr* addr ) 465 { 466 version(BigEndian) 467 return (addr.s6_addr32[0] & 0xff0f0000) == 0xff020000; 468 else 469 return (addr.s6_addr32[0] & 0x00000fff) == 0x000002ff; 470 } 471 472 extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in6_addr* addr ) 473 { 474 version(BigEndian) 475 return (addr.s6_addr32[0] & 0xff0f0000) == 0xff050000; 476 else 477 return (addr.s6_addr32[0] & 0x00000fff) == 0x000005ff; 478 } 479 480 extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in6_addr* addr ) 481 { 482 version(BigEndian) 483 return (addr.s6_addr32[0] & 0xff0f0000) == 0xff080000; 484 else 485 return (addr.s6_addr32[0] & 0x00000fff) == 0x000008ff; 486 } 487 488 extern (D) int IN6_IS_ADDR_MC_GLOBAL( in6_addr* addr ) 489 { 490 version(BigEndian) 491 return (addr.s6_addr32[0] & 0xff0f0000) == 0xff0e0000; 492 else 493 return (addr.s6_addr32[0] & 0x00000fff) == 0x00000eff; 494 } 495 } 496 497 498 // 499 // Raw Sockets (RS) 500 // 501 /* 502 IPPROTO_RAW 503 */ 504 505 version ( linux ) 506 { 507 const uint IPPROTO_RAW = 255; 508 } 509 else version ( solaris ) 510 { 511 const uint IPPROTO_RAW = 255; 512 }