00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #if !defined (_ink_inet_h_)
00026 #define _ink_inet_h_
00027
00028 #include <netinet/in.h>
00029 #include <netdb.h>
00030 #include <ink_memory.h>
00031 #include <sys/socket.h>
00032 #include <ts/ink_apidefs.h>
00033 #include <ts/TsBuffer.h>
00034
00035 #define INK_GETHOSTBYNAME_R_DATA_SIZE 1024
00036 #define INK_GETHOSTBYADDR_R_DATA_SIZE 1024
00037
00038 #if ! TS_HAS_IN6_IS_ADDR_UNSPECIFIED
00039 #if defined(IN6_IS_ADDR_UNSPECIFIED)
00040 #undef IN6_IS_ADDR_UNSPECIFIED
00041 #endif
00042 static inline bool IN6_IS_ADDR_UNSPECIFIED(in6_addr const* addr) {
00043 uint64_t const* w = reinterpret_cast<uint64_t const*>(addr);
00044 return 0 == w[0] && 0 == w[1];
00045 }
00046 #endif
00047
00048 struct IpAddr;
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 union IpEndpoint {
00066 typedef IpEndpoint self;
00067
00068 struct sockaddr sa;
00069 struct sockaddr_in sin;
00070 struct sockaddr_in6 sin6;
00071
00072 self& assign(
00073 sockaddr const* ip
00074 );
00075
00076 self& assign(
00077 IpAddr const& addr,
00078 in_port_t port = 0
00079 );
00080
00081
00082 bool isValid() const;
00083
00084 bool isIp4() const;
00085
00086 bool isIp6() const;
00087
00088 uint16_t family() const;
00089
00090
00091
00092
00093 self& setToAnyAddr(
00094 int family
00095 );
00096
00097
00098
00099 self& setToLoopback(
00100 int family
00101 );
00102
00103
00104
00105 in_port_t& port();
00106
00107 in_port_t port() const;
00108
00109 operator sockaddr* () { return &sa; }
00110 operator sockaddr const* () const { return &sa; }
00111 };
00112
00113 struct ink_gethostbyname_r_data
00114 {
00115 int herrno;
00116 struct hostent ent;
00117 char buf[INK_GETHOSTBYNAME_R_DATA_SIZE];
00118 };
00119
00120 struct ink_gethostbyaddr_r_data
00121 {
00122 int herrno;
00123 struct hostent ent;
00124 char buf[INK_GETHOSTBYADDR_R_DATA_SIZE];
00125 };
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 struct hostent *ink_gethostbyname_r(char *hostname, ink_gethostbyname_r_data * data);
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 struct hostent *ink_gethostbyaddr_r(char *ip, int len, int type, ink_gethostbyaddr_r_data * data);
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 int
00165 ats_ip_parse(
00166 ts::ConstBuffer src,
00167 ts::ConstBuffer* addr,
00168 ts::ConstBuffer* port
00169 );
00170
00171
00172
00173
00174
00175
00176
00177 int
00178 ats_ip_check_characters(ts::ConstBuffer text);
00179
00180
00181
00182
00183
00184
00185
00186 inkcoreapi uint32_t ats_inet_addr(const char *s);
00187
00188 const char *ats_ip_ntop(const struct sockaddr *addr, char *dst, size_t size);
00189
00190
00191
00192 static size_t const TS_IP6_SIZE = sizeof(in6_addr);
00193
00194
00195
00196 inline void ats_ip_invalidate(sockaddr* addr) {
00197 addr->sa_family = AF_UNSPEC;
00198 }
00199 inline void ats_ip_invalidate(sockaddr_in6* addr) {
00200 addr->sin6_family = AF_UNSPEC;
00201 }
00202 inline void ats_ip_invalidate(IpEndpoint* ip) {
00203 ip->sa.sa_family = AF_UNSPEC;
00204 }
00205
00206
00207
00208
00209 char const*
00210 ats_ip_family_name(int family);
00211
00212
00213
00214 inline bool ats_is_ip(sockaddr const* addr) {
00215 return addr
00216 && (AF_INET == addr->sa_family || AF_INET6 == addr->sa_family);
00217 }
00218
00219 inline bool ats_is_ip(IpEndpoint const* addr) {
00220 return addr
00221 && (AF_INET == addr->sa.sa_family || AF_INET6 == addr->sa.sa_family);
00222 }
00223
00224
00225 inline bool ats_is_ip(int family) {
00226 return AF_INET == family || AF_INET6 == family;
00227 }
00228
00229
00230 inline bool ats_is_ip4(sockaddr const* addr) {
00231 return addr && AF_INET == addr->sa_family;
00232 }
00233
00234
00235
00236 inline bool ats_is_ip4(IpEndpoint const* addr) {
00237 return addr && AF_INET == addr->sa.sa_family;
00238 }
00239
00240
00241 inline bool ats_is_ip6(sockaddr const* addr) {
00242 return addr && AF_INET6 == addr->sa_family;
00243 }
00244
00245
00246
00247 inline bool ats_is_ip6(IpEndpoint const* addr) {
00248 return addr && AF_INET6 == addr->sa.sa_family;
00249 }
00250
00251
00252 inline bool ats_ip_are_compatible(
00253 sockaddr const* lhs,
00254 sockaddr const* rhs
00255 ) {
00256 return lhs->sa_family == rhs->sa_family;
00257 }
00258
00259 inline bool ats_ip_are_compatible(
00260 IpEndpoint const* lhs,
00261 IpEndpoint const* rhs
00262 ) {
00263 return ats_ip_are_compatible(&lhs->sa, &rhs->sa);
00264 }
00265
00266 inline bool ats_ip_are_compatible(
00267 int lhs,
00268 sockaddr const* rhs
00269 ) {
00270 return lhs == rhs->sa_family;
00271 }
00272
00273 inline bool ats_ip_are_compatible(
00274 sockaddr const* lhs,
00275 int rhs
00276 ) {
00277 return lhs->sa_family == rhs;
00278 }
00279
00280
00281
00282
00283
00284
00285
00286 inline sockaddr* ats_ip_sa_cast(sockaddr_storage* a) {
00287 return static_cast<sockaddr*>(static_cast<void*>(a));
00288 }
00289 inline sockaddr const* ats_ip_sa_cast(sockaddr_storage const* a) {
00290 return static_cast<sockaddr const*>(static_cast<void const*>(a));
00291 }
00292
00293 inline sockaddr* ats_ip_sa_cast(sockaddr_in* a) {
00294 return static_cast<sockaddr*>(static_cast<void*>(a));
00295 }
00296 inline sockaddr const* ats_ip_sa_cast(sockaddr_in const* a) {
00297 return static_cast<sockaddr const*>(static_cast<void const*>(a));
00298 }
00299
00300 inline sockaddr* ats_ip_sa_cast(sockaddr_in6* a) {
00301 return static_cast<sockaddr*>(static_cast<void*>(a));
00302 }
00303 inline sockaddr const* ats_ip_sa_cast(sockaddr_in6 const* a) {
00304 return static_cast<sockaddr const*>(static_cast<void const*>(a));
00305 }
00306
00307 inline sockaddr_storage* ats_ip_ss_cast(sockaddr* a) {
00308 return static_cast<sockaddr_storage*>(static_cast<void*>(a));
00309 }
00310 inline sockaddr_storage const* ats_ip_ss_cast(sockaddr const* a) {
00311 return static_cast<sockaddr_storage const*>(static_cast<void const*>(a));
00312 }
00313
00314 inline sockaddr_in* ats_ip4_cast(sockaddr* a) {
00315 return static_cast<sockaddr_in*>(static_cast<void*>(a));
00316 }
00317 inline sockaddr_in const* ats_ip4_cast(sockaddr const* a) {
00318 return static_cast<sockaddr_in const*>(static_cast<void const*>(a));
00319 }
00320
00321 inline sockaddr_in& ats_ip4_cast(sockaddr& a) {
00322 return *static_cast<sockaddr_in*>(static_cast<void*>(&a));
00323 }
00324 inline sockaddr_in const& ats_ip4_cast(sockaddr const& a) {
00325 return *static_cast<sockaddr_in const*>(static_cast<void const*>(&a));
00326 }
00327
00328 inline sockaddr_in* ats_ip4_cast(sockaddr_in6* a) {
00329 return static_cast<sockaddr_in*>(static_cast<void*>(a));
00330 }
00331 inline sockaddr_in const* ats_ip4_cast(sockaddr_in6 const* a) {
00332 return static_cast<sockaddr_in const*>(static_cast<void const*>(a));
00333 }
00334
00335 inline sockaddr_in& ats_ip4_cast(sockaddr_in6& a) {
00336 return *static_cast<sockaddr_in*>(static_cast<void*>(&a));
00337 }
00338 inline sockaddr_in const& ats_ip4_cast(sockaddr_in6 const& a) {
00339 return *static_cast<sockaddr_in const*>(static_cast<void const*>(&a));
00340 }
00341
00342 inline sockaddr_in6* ats_ip6_cast(sockaddr* a) {
00343 return static_cast<sockaddr_in6*>(static_cast<void*>(a));
00344 }
00345 inline sockaddr_in6 const* ats_ip6_cast(sockaddr const* a) {
00346 return static_cast<sockaddr_in6 const*>(static_cast<void const*>(a));
00347 }
00348 inline sockaddr_in6& ats_ip6_cast(sockaddr& a) {
00349 return *static_cast<sockaddr_in6*>(static_cast<void*>(&a));
00350 }
00351 inline sockaddr_in6 const& ats_ip6_cast(sockaddr const& a) {
00352 return *static_cast<sockaddr_in6 const*>(static_cast<void const*>(&a));
00353 }
00354
00355
00356 inline size_t ats_ip_size(
00357 sockaddr const* addr
00358 ) {
00359 return AF_INET == addr->sa_family ? sizeof(sockaddr_in)
00360 : AF_INET6 == addr->sa_family ? sizeof(sockaddr_in6)
00361 : 0
00362 ;
00363 }
00364 inline size_t ats_ip_size(
00365 IpEndpoint const* addr
00366 ) {
00367 return AF_INET == addr->sa.sa_family ? sizeof(sockaddr_in)
00368 : AF_INET6 == addr->sa.sa_family ? sizeof(sockaddr_in6)
00369 : 0
00370 ;
00371 }
00372
00373 inline size_t ats_ip_addr_size(
00374 sockaddr const* addr
00375 ) {
00376 return AF_INET == addr->sa_family ? sizeof(in_addr_t)
00377 : AF_INET6 == addr->sa_family ? sizeof(in6_addr)
00378 : 0
00379 ;
00380 }
00381 inline size_t ats_ip_addr_size(
00382 IpEndpoint const* addr
00383 ) {
00384 return AF_INET == addr->sa.sa_family ? sizeof(in_addr_t)
00385 : AF_INET6 == addr->sa.sa_family ? sizeof(in6_addr)
00386 : 0
00387 ;
00388 }
00389
00390
00391
00392
00393
00394
00395
00396
00397 inline in_port_t& ats_ip_port_cast(sockaddr* sa) {
00398 static in_port_t dummy = 0;
00399 return ats_is_ip4(sa)
00400 ? ats_ip4_cast(sa)->sin_port
00401 : ats_is_ip6(sa)
00402 ? ats_ip6_cast(sa)->sin6_port
00403 : (dummy = 0)
00404 ;
00405 }
00406 inline in_port_t const& ats_ip_port_cast(sockaddr const* sa) {
00407 return ats_ip_port_cast(const_cast<sockaddr*>(sa));
00408 }
00409 inline in_port_t const& ats_ip_port_cast(IpEndpoint const* ip) {
00410 return ats_ip_port_cast(const_cast<sockaddr*>(&ip->sa));
00411 }
00412 inline in_port_t& ats_ip_port_cast(IpEndpoint* ip) {
00413 return ats_ip_port_cast(&ip->sa);
00414 }
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 inline in_addr_t& ats_ip4_addr_cast(sockaddr* addr) {
00425 static in_addr_t dummy = 0;
00426 return ats_is_ip4(addr)
00427 ? ats_ip4_cast(addr)->sin_addr.s_addr
00428 : (dummy = 0)
00429 ;
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440 inline in_addr_t const& ats_ip4_addr_cast(sockaddr const* addr) {
00441 static in_addr_t dummy = 0;
00442 return ats_is_ip4(addr)
00443 ? ats_ip4_cast(addr)->sin_addr.s_addr
00444 : static_cast<in_addr_t const&>(dummy = 0)
00445 ;
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457 inline in_addr_t& ats_ip4_addr_cast(IpEndpoint* ip) {
00458 return ats_ip4_addr_cast(&ip->sa);
00459 }
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 inline in_addr_t const& ats_ip4_addr_cast(IpEndpoint const* ip) {
00471 return ats_ip4_addr_cast(&ip->sa);
00472 }
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 inline in6_addr& ats_ip6_addr_cast(sockaddr* addr) {
00483 return ats_ip6_cast(addr)->sin6_addr;
00484 }
00485 inline in6_addr const& ats_ip6_addr_cast(sockaddr const* addr) {
00486 return ats_ip6_cast(addr)->sin6_addr;
00487 }
00488 inline in6_addr& ats_ip6_addr_cast(IpEndpoint* ip) {
00489 return ip->sin6.sin6_addr;
00490 }
00491 inline in6_addr const& ats_ip6_addr_cast(IpEndpoint const* ip) {
00492 return ip->sin6.sin6_addr;
00493 }
00494
00495
00496
00497
00498
00499
00500
00501 inline uint32_t* ats_ip_addr32_cast(sockaddr* addr) {
00502 uint32_t* zret = 0;
00503 switch(addr->sa_family) {
00504 case AF_INET: zret = reinterpret_cast<uint32_t*>(&ats_ip4_addr_cast(addr)); break;
00505 case AF_INET6: zret = reinterpret_cast<uint32_t*>(&ats_ip6_addr_cast(addr)); break;
00506 }
00507 return zret;
00508 }
00509 inline uint32_t const* ats_ip_addr32_cast(sockaddr const* addr) {
00510 return ats_ip_addr32_cast(const_cast<sockaddr*>(addr));
00511 }
00512
00513
00514
00515
00516
00517
00518
00519
00520 inline uint8_t* ats_ip_addr8_cast(sockaddr* addr) {
00521 uint8_t* zret = 0;
00522 switch(addr->sa_family) {
00523 case AF_INET: zret = reinterpret_cast<uint8_t*>(&ats_ip4_addr_cast(addr)); break;
00524 case AF_INET6: zret = reinterpret_cast<uint8_t*>(&ats_ip6_addr_cast(addr)); break;
00525 }
00526 return zret;
00527 }
00528 inline uint8_t const* ats_ip_addr8_cast(sockaddr const* addr) {
00529 return ats_ip_addr8_cast(const_cast<sockaddr*>(addr));
00530 }
00531 inline uint8_t* ats_ip_addr8_cast(IpEndpoint* ip) {
00532 return ats_ip_addr8_cast(&ip->sa);
00533 }
00534 inline uint8_t const* ats_ip_addr8_cast(IpEndpoint const* ip) {
00535 return ats_ip_addr8_cast(&ip->sa);
00536 }
00537
00538
00539
00540 inline bool ats_is_ip_loopback(sockaddr const* ip) {
00541 return ip
00542 && (
00543 (AF_INET == ip->sa_family && 0x7F == ats_ip_addr8_cast(ip)[0])
00544 ||
00545 (AF_INET6 == ip->sa_family && IN6_IS_ADDR_LOOPBACK(&ats_ip6_addr_cast(ip)))
00546 );
00547 }
00548
00549
00550
00551 inline bool ats_is_ip_loopback(IpEndpoint const* ip) {
00552 return ats_is_ip_loopback(&ip->sa);
00553 }
00554
00555
00556
00557 inline bool ats_is_ip_multicast(sockaddr const* ip) {
00558 return ip
00559 && (
00560 (AF_INET == ip->sa_family && 0xe == *ats_ip_addr8_cast(ip))
00561 ||
00562 (AF_INET6 == ip->sa_family && IN6_IS_ADDR_MULTICAST(&ats_ip6_addr_cast(ip)))
00563 );
00564 }
00565
00566
00567 inline bool ats_is_ip_multicast(IpEndpoint const* ip) {
00568 return ats_is_ip_multicast(&ip->sa);
00569 }
00570
00571
00572
00573 inline bool
00574 ats_is_ip_private(sockaddr const* ip) {
00575 bool zret = false;
00576 if (ats_is_ip4(ip)) {
00577 in_addr_t a = ats_ip4_addr_cast(ip);
00578 zret = ((a & htonl(0xFF000000)) == htonl(0x0A000000)) ||
00579 ((a & htonl(0xFFC00000)) == htonl(0x64400000)) ||
00580 ((a & htonl(0xFFF00000)) == htonl(0xAC100000)) ||
00581 ((a & htonl(0xFFFF0000)) == htonl(0xC0A80000))
00582 ;
00583 } else if (ats_is_ip6(ip)) {
00584 in6_addr a = ats_ip6_addr_cast(ip);
00585 zret = ((a.s6_addr[0] & 0xFE) == 0xFC)
00586 ;
00587 }
00588 return zret;
00589 }
00590
00591
00592
00593 inline bool
00594 ats_is_ip_private(IpEndpoint const* ip) {
00595 return ats_is_ip_private(&ip->sa);
00596 }
00597
00598
00599
00600 inline bool
00601 ats_is_ip_linklocal(sockaddr const* ip) {
00602 bool zret = false;
00603 if (ats_is_ip4(ip)) {
00604 in_addr_t a = ats_ip4_addr_cast(ip);
00605 zret = ((a & htonl(0xFFFF0000)) == htonl(0xA9FE0000))
00606 ;
00607 } else if (ats_is_ip6(ip)) {
00608 in6_addr a = ats_ip6_addr_cast(ip);
00609 zret = ((a.s6_addr[0] == 0xFE) && ((a.s6_addr[1] & 0xC0) == 0x80))
00610 ;
00611 }
00612 return zret;
00613 }
00614
00615
00616
00617 inline bool
00618 ats_is_ip_linklocal(IpEndpoint const* ip) {
00619 return ats_is_ip_linklocal(&ip->sa);
00620 }
00621
00622
00623
00624 inline bool ats_is_ip_any(sockaddr const* ip) {
00625 return (ats_is_ip4(ip) && INADDR_ANY == ats_ip4_addr_cast(ip)) ||
00626 (ats_is_ip6(ip) && IN6_IS_ADDR_UNSPECIFIED(&ats_ip6_addr_cast(ip)))
00627 ;
00628 }
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 inline bool ats_ip_copy(
00640 sockaddr* dst,
00641 sockaddr const* src
00642 ) {
00643 size_t n = 0;
00644 if (src) {
00645 switch (src->sa_family) {
00646 case AF_INET: n = sizeof(sockaddr_in); break;
00647 case AF_INET6: n = sizeof(sockaddr_in6); break;
00648 }
00649 }
00650 if (n) {
00651 memcpy(dst, src, n);
00652 #if HAVE_STRUCT_SOCKADDR_SA_LEN
00653 dst->sa_len = n;
00654 #endif
00655 } else {
00656 ats_ip_invalidate(dst);
00657 }
00658 return n != 0;
00659 }
00660
00661 inline bool ats_ip_copy(
00662 IpEndpoint* dst,
00663 sockaddr const* src
00664 ) {
00665 return ats_ip_copy(&dst->sa, src);
00666 }
00667 inline bool ats_ip_copy(
00668 IpEndpoint* dst,
00669 IpEndpoint const* src
00670 ) {
00671 return ats_ip_copy(&dst->sa, &src->sa);
00672 }
00673 inline bool ats_ip_copy(
00674 sockaddr* dst,
00675 IpEndpoint const* src
00676 ) {
00677 return ats_ip_copy(dst, &src->sa);
00678 }
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698 inline int ats_ip_addr_cmp(
00699 sockaddr const* lhs,
00700 sockaddr const* rhs
00701 ) {
00702 int zret = 0;
00703 uint16_t rtype = rhs->sa_family;
00704 uint16_t ltype = lhs->sa_family;
00705
00706
00707
00708 if (AF_INET == ltype) {
00709 if (AF_INET == rtype) {
00710 in_addr_t la = ntohl(ats_ip4_cast(lhs)->sin_addr.s_addr);
00711 in_addr_t ra = ntohl(ats_ip4_cast(rhs)->sin_addr.s_addr);
00712 if (la < ra) zret = -1;
00713 else if (la > ra) zret = 1;
00714 else zret = 0;
00715 } else if (AF_INET6 == rtype) {
00716 zret = -1;
00717 } else {
00718 zret = 1;
00719 }
00720 } else if (AF_INET6 == ltype) {
00721 if (AF_INET6 == rtype) {
00722 sockaddr_in6 const* lhs_in6 = ats_ip6_cast(lhs);
00723 zret = memcmp(
00724 &lhs_in6->sin6_addr,
00725 &ats_ip6_cast(rhs)->sin6_addr,
00726 sizeof(lhs_in6->sin6_addr)
00727 );
00728 } else {
00729 zret = 1;
00730 }
00731 } else if (AF_INET == rtype || AF_INET6 == rtype) {
00732
00733 zret = -1;
00734 } else {
00735
00736 zret = 0;
00737 }
00738
00739 return zret;
00740 }
00741
00742
00743
00744
00745
00746 inline int ats_ip_addr_cmp(IpEndpoint const* lhs, IpEndpoint const* rhs) {
00747 return ats_ip_addr_cmp(&lhs->sa, &rhs->sa);
00748 }
00749
00750
00751
00752
00753
00754 inline bool ats_ip_addr_eq(sockaddr const* lhs, sockaddr const* rhs) {
00755 return 0 == ats_ip_addr_cmp(lhs, rhs);
00756 }
00757 inline bool ats_ip_addr_eq(IpEndpoint const* lhs, IpEndpoint const* rhs) {
00758 return 0 == ats_ip_addr_cmp(&lhs->sa, &rhs->sa);
00759 }
00760
00761 inline bool operator == (IpEndpoint const& lhs, IpEndpoint const& rhs) {
00762 return 0 == ats_ip_addr_cmp(&lhs.sa, &rhs.sa);
00763 }
00764 inline bool operator != (IpEndpoint const& lhs, IpEndpoint const& rhs) {
00765 return 0 != ats_ip_addr_cmp(&lhs.sa, &rhs.sa);
00766 }
00767
00768
00769 inline bool ats_ip_addr_port_eq(sockaddr const* lhs, sockaddr const* rhs) {
00770 bool zret = false;
00771 if (lhs->sa_family == rhs->sa_family && ats_ip_port_cast(lhs) == ats_ip_port_cast(rhs)) {
00772 if (AF_INET == lhs->sa_family)
00773 zret = ats_ip4_cast(lhs)->sin_addr.s_addr == ats_ip4_cast(rhs)->sin_addr.s_addr;
00774 else if (AF_INET6 == lhs->sa_family)
00775 zret = 0 == memcmp(&ats_ip6_cast(lhs)->sin6_addr, &ats_ip6_cast(rhs)->sin6_addr, sizeof(in6_addr));
00776 }
00777 return zret;
00778 }
00779
00780
00781
00782
00783
00784
00785 inline in_port_t ats_ip_port_host_order(
00786 sockaddr const* addr
00787 ) {
00788
00789
00790 return ntohs(ats_ip_port_cast(const_cast<sockaddr*>(addr)));
00791 }
00792
00793
00794
00795
00796 inline in_port_t ats_ip_port_host_order(
00797 IpEndpoint const* ip
00798 ) {
00799
00800
00801 return ntohs(ats_ip_port_cast(const_cast<sockaddr*>(&ip->sa)));
00802 }
00803
00804
00805
00806
00807
00808 inline in_addr_t ats_ip4_addr_host_order(
00809 sockaddr const* addr
00810 ) {
00811 return ntohl(ats_ip4_addr_cast(const_cast<sockaddr*>(addr)));
00812 }
00813
00814
00815 inline sockaddr* ats_ip4_set(
00816 sockaddr_in* dst,
00817 in_addr_t addr,
00818 in_port_t port = 0
00819 ) {
00820 ink_zero(*dst);
00821 #if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
00822 dst->sin_len = sizeof(sockaddr_in);
00823 #endif
00824 dst->sin_family = AF_INET;
00825 dst->sin_addr.s_addr = addr;
00826 dst->sin_port = port;
00827 return ats_ip_sa_cast(dst);
00828 }
00829
00830
00831
00832
00833 inline sockaddr* ats_ip4_set(
00834 IpEndpoint* dst,
00835 in_addr_t ip4,
00836 in_port_t port = 0
00837 ) {
00838 return ats_ip4_set(&dst->sin, ip4, port);
00839 }
00840
00841
00842
00843
00844
00845
00846 inline sockaddr* ats_ip4_set(
00847 sockaddr* dst,
00848 in_addr_t ip4,
00849 in_port_t port = 0
00850 ) {
00851 return ats_ip4_set(ats_ip4_cast(dst), ip4, port);
00852 }
00853
00854
00855
00856 inline sockaddr* ats_ip6_set(
00857 sockaddr_in6* dst,
00858 in6_addr const& addr,
00859 in_port_t port = 0
00860 ) {
00861 ink_zero(*dst);
00862 #if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
00863 dst->sin6_len = sizeof(sockaddr_in6);
00864 #endif
00865 dst->sin6_family = AF_INET6;
00866 memcpy(&dst->sin6_addr, &addr, sizeof addr);
00867 dst->sin6_port = port;
00868 return ats_ip_sa_cast(dst);
00869 }
00870
00871
00872
00873 inline sockaddr* ats_ip6_set(
00874 sockaddr* dst,
00875 in6_addr const& addr,
00876 in_port_t port = 0
00877 ) {
00878 return ats_ip6_set(ats_ip6_cast(dst), addr, port);
00879 }
00880
00881
00882
00883 inline sockaddr* ats_ip6_set(
00884 IpEndpoint* dst,
00885 in6_addr const& addr,
00886 in_port_t port = 0
00887 ) {
00888 return ats_ip6_set(&dst->sin6, addr, port);
00889 }
00890
00891
00892
00893
00894 char const* ats_ip_ntop(
00895 const sockaddr *addr,
00896 char *dst,
00897 size_t size
00898 );
00899
00900
00901
00902
00903 inline char const* ats_ip_ntop(
00904 IpEndpoint const* addr,
00905 char *dst,
00906 size_t size
00907 ) {
00908 return ats_ip_ntop(&addr->sa, dst, size);
00909 }
00910
00911
00912 static size_t const INET6_ADDRPORTSTRLEN = INET6_ADDRSTRLEN + 6;
00913
00914 typedef char ip_text_buffer[INET6_ADDRSTRLEN];
00915
00916 typedef char ip_port_text_buffer[INET6_ADDRPORTSTRLEN];
00917
00918
00919
00920
00921 char const* ats_ip_nptop(
00922 const sockaddr *addr,
00923 char *dst,
00924 size_t size
00925 );
00926
00927
00928
00929
00930 inline char const* ats_ip_nptop(
00931 IpEndpoint const*addr,
00932 char *dst,
00933 size_t size
00934 ) {
00935 return ats_ip_nptop(&addr->sa, dst, size);
00936 }
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955 int ats_ip_pton(
00956 const ts::ConstBuffer& text,
00957 sockaddr* addr
00958 );
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971 inline int ats_ip_pton(
00972 char const* text,
00973 sockaddr_in6* addr
00974 ) {
00975 return ats_ip_pton(ts::ConstBuffer(text, strlen(text)), ats_ip_sa_cast(addr));
00976 }
00977
00978 inline int ats_ip_pton(
00979 const ts::ConstBuffer& text,
00980 IpEndpoint* addr
00981 ) {
00982 return ats_ip_pton(text, &addr->sa);
00983 }
00984
00985 inline int ats_ip_pton(
00986 const char * text,
00987 IpEndpoint* addr
00988 ) {
00989 return ats_ip_pton(ts::ConstBuffer(text, strlen(text)), &addr->sa);
00990 }
00991
00992 inline int ats_ip_pton(
00993 const char * text,
00994 sockaddr * addr
00995 ) {
00996 return ats_ip_pton(ts::ConstBuffer(text, strlen(text)), addr);
00997 }
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024 int
01025 ats_ip_getbestaddrinfo(
01026 char const* name,
01027 IpEndpoint* ip4,
01028 IpEndpoint* ip6
01029 );
01030
01031
01032
01033 uint32_t ats_ip_hash(sockaddr const* addr);
01034
01035
01036
01037
01038
01039
01040 int
01041 ats_ip_to_hex(
01042 sockaddr const* addr,
01043 char* dst,
01044 size_t len
01045 );
01046
01047
01048
01049
01050
01051
01052 struct IpAddr {
01053 typedef IpAddr self;
01054
01055
01056 IpAddr() : _family(AF_UNSPEC) {}
01057
01058 explicit IpAddr(
01059 in_addr_t addr
01060 ) : _family(AF_INET) {
01061 _addr._ip4 = addr;
01062 }
01063
01064 explicit IpAddr(
01065 in6_addr const& addr
01066 ) : _family(AF_INET6) {
01067 _addr._ip6 = addr;
01068 }
01069
01070 explicit IpAddr(sockaddr const* addr) { this->assign(addr); }
01071
01072 explicit IpAddr(sockaddr_in6 const& addr) { this->assign(ats_ip_sa_cast(&addr)); }
01073
01074 explicit IpAddr(sockaddr_in6 const* addr) { this->assign(ats_ip_sa_cast(addr)); }
01075
01076 explicit IpAddr(IpEndpoint const& addr) { this->assign(&addr.sa); }
01077
01078 explicit IpAddr(IpEndpoint const* addr) { this->assign(&addr->sa); }
01079
01080
01081 self& assign(
01082 sockaddr const* addr
01083 );
01084
01085
01086 self& operator = (IpEndpoint const& ip) {
01087 return this->assign(&ip.sa);
01088 }
01089
01090 self& operator = (
01091 in_addr_t ip
01092 );
01093
01094 self& operator = (
01095 in6_addr const& ip
01096 );
01097
01098
01099
01100
01101
01102
01103 int load(
01104 char const* str
01105 );
01106
01107
01108
01109 char* toString(
01110 char* dest,
01111 size_t len
01112 ) const;
01113
01114
01115 bool operator==(self const& that) const {
01116 return _family == AF_INET
01117 ? (that._family == AF_INET && _addr._ip4 == that._addr._ip4)
01118 : _family == AF_INET6
01119 ? (that._family == AF_INET6
01120 && 0 == memcmp(&_addr._ip6, &that._addr._ip6, TS_IP6_SIZE)
01121 )
01122 : (_family == AF_UNSPEC && that._family == AF_UNSPEC)
01123 ;
01124 }
01125
01126
01127 bool operator!=(self const& that) {
01128 return ! (*this == that);
01129 }
01130
01131
01132
01133 bool isCompatibleWith(self const& that);
01134
01135
01136
01137 uint16_t family() const;
01138
01139 bool isIp4() const;
01140
01141 bool isIp6() const;
01142
01143
01144 bool isValid() const { return _family == AF_INET || _family == AF_INET6; }
01145
01146 self& invalidate() { _family = AF_UNSPEC; return *this; }
01147
01148 bool isMulticast() const;
01149
01150 uint16_t _family;
01151
01152 union {
01153 in_addr_t _ip4;
01154 in6_addr _ip6;
01155 uint8_t _byte[TS_IP6_SIZE];
01156 } _addr;
01157
01158
01159 static self const INVALID;
01160 };
01161
01162 inline IpAddr&
01163 IpAddr::operator = (in_addr_t ip) {
01164 _family = AF_INET;
01165 _addr._ip4 = ip;
01166 return *this;
01167 }
01168
01169 inline IpAddr&
01170 IpAddr::operator = (in6_addr const& ip) {
01171 _family = AF_INET6;
01172 _addr._ip6 = ip;
01173 return *this;
01174 }
01175
01176 inline uint16_t IpAddr::family() const { return _family; }
01177
01178 inline bool
01179 IpAddr::isCompatibleWith(self const& that) {
01180 return this->isValid() && _family == that._family;
01181 }
01182
01183 inline bool IpAddr::isIp4() const { return AF_INET == _family; }
01184 inline bool IpAddr::isIp6() const { return AF_INET6 == _family; }
01185
01186 inline IpAddr&
01187 IpAddr::assign(sockaddr const* addr) {
01188 if (addr) {
01189 _family = addr->sa_family;
01190 if (ats_is_ip4(addr)) {
01191 _addr._ip4 = ats_ip4_addr_cast(addr);
01192 } else if (ats_is_ip6(addr)) {
01193 _addr._ip6 = ats_ip6_addr_cast(addr);
01194 } else {
01195 _family = AF_UNSPEC;
01196 }
01197 } else {
01198 _family = AF_UNSPEC;
01199 }
01200 return *this;
01201 }
01202
01203
01204 bool operator == (IpAddr const& lhs, sockaddr const* rhs);
01205 inline bool operator == (sockaddr const* lhs, IpAddr const& rhs) {
01206 return rhs == lhs;
01207 }
01208 inline bool operator != (IpAddr const& lhs, sockaddr const* rhs) {
01209 return ! (lhs == rhs);
01210 }
01211 inline bool operator != (sockaddr const* lhs, IpAddr const& rhs) {
01212 return ! (rhs == lhs);
01213 }
01214 inline bool operator == (IpAddr const& lhs, IpEndpoint const& rhs) {
01215 return lhs == &rhs.sa;
01216 }
01217 inline bool operator == (IpEndpoint const& lhs, IpAddr const& rhs) {
01218 return &lhs.sa == rhs;
01219 }
01220 inline bool operator != (IpAddr const& lhs, IpEndpoint const& rhs) {
01221 return ! (lhs == &rhs.sa);
01222 }
01223 inline bool operator != (IpEndpoint const& lhs, IpAddr const& rhs) {
01224 return ! (rhs == &lhs.sa);
01225 }
01226
01227
01228
01229 sockaddr* ats_ip_set(
01230 sockaddr* dst,
01231 IpAddr const& addr,
01232 in_port_t port = 0
01233 );
01234
01235
01236
01237
01238
01239 inline int ats_ip_pton(
01240 char const* text,
01241 IpAddr& addr
01242 ) {
01243 return addr.load(text) ? 0 : -1;
01244 }
01245
01246 inline IpEndpoint&
01247 IpEndpoint::assign(IpAddr const& addr, in_port_t port) {
01248 ats_ip_set(&sa, addr, port);
01249 return *this;
01250 }
01251
01252 inline IpEndpoint&
01253 IpEndpoint::assign(sockaddr const* ip) {
01254 ats_ip_copy(&sa, ip);
01255 return *this;
01256 }
01257
01258 inline in_port_t&
01259 IpEndpoint::port() {
01260 return ats_ip_port_cast(&sa);
01261 }
01262
01263 inline in_port_t
01264 IpEndpoint::port() const {
01265 return ats_ip_port_cast(&sa);
01266 }
01267
01268 inline bool
01269 IpEndpoint::isValid() const {
01270 return ats_is_ip(this);
01271 }
01272
01273 inline bool IpEndpoint::isIp4() const { return AF_INET == sa.sa_family; }
01274 inline bool IpEndpoint::isIp6() const { return AF_INET6 == sa.sa_family; }
01275 inline uint16_t IpEndpoint::family() const { return sa.sa_family; }
01276
01277 inline IpEndpoint&
01278 IpEndpoint::setToAnyAddr(int family) {
01279 ink_zero(*this);
01280 sa.sa_family = family;
01281 if (AF_INET == family) {
01282 sin.sin_addr.s_addr = INADDR_ANY;
01283 #if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
01284 sin.sin_len = sizeof(sockaddr_in);
01285 #endif
01286 } else if (AF_INET6 == family) {
01287 sin6.sin6_addr = in6addr_any;
01288 #if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
01289 sin6.sin6_len = sizeof(sockaddr_in6);
01290 #endif
01291 }
01292 return *this;
01293 }
01294
01295 inline IpEndpoint&
01296 IpEndpoint::setToLoopback(int family) {
01297 ink_zero(*this);
01298 sa.sa_family = family;
01299 if (AF_INET == family) {
01300 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
01301 #if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
01302 sin.sin_len = sizeof(sockaddr_in);
01303 #endif
01304 } else if (AF_INET6 == family) {
01305 sin6.sin6_addr = in6addr_loopback;
01306 #if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
01307 sin6.sin6_len = sizeof(sockaddr_in6);
01308 #endif
01309 }
01310 return *this;
01311 }
01312
01313 #endif // _ink_inet.h