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