INET_Addr.cpp

Go to the documentation of this file.
00001 // $Id: INET_Addr.cpp 79332 2007-08-13 20:30:44Z sowayaa $
00002 
00003 // Defines the Internet domain address family address format.
00004 
00005 #include "ace/INET_Addr.h"
00006 
00007 #if !defined (__ACE_INLINE__)
00008 #include "ace/INET_Addr.inl"
00009 #endif /* __ACE_INLINE__ */
00010 
00011 #include "ace/Log_Msg.h"
00012 #include "ace/OS_NS_stdio.h"
00013 #include "ace/OS_NS_errno.h"
00014 #include "ace/OS_NS_stdlib.h"
00015 #include "ace/OS_Memory.h"
00016 #include "ace/OS_NS_arpa_inet.h"
00017 #include "ace/OS_NS_netdb.h"
00018 #include "ace/OS_NS_unistd.h"
00019 #include "ace/OS_NS_sys_socket.h"
00020 
00021 ACE_RCSID (ace,
00022            INET_Addr,
00023            "$Id: INET_Addr.cpp 79332 2007-08-13 20:30:44Z sowayaa $")
00024 
00025 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00026 
00027 ACE_ALLOC_HOOK_DEFINE(ACE_INET_Addr)
00028 
00029 // Transform the current address into string format.
00030 
00031 int
00032 ACE_INET_Addr::addr_to_string (ACE_TCHAR s[],
00033                                size_t size,
00034                                int ipaddr_format) const
00035 {
00036   ACE_TRACE ("ACE_INET_Addr::addr_to_string");
00037 
00038   // XXX Can we (should we) include the scope id for IPv6 addresses?
00039   char  hoststr[MAXHOSTNAMELEN+1];
00040 
00041   bool result = false;
00042   if (ipaddr_format == 0)
00043     result = (this->get_host_name (hoststr, MAXHOSTNAMELEN+1) == 0);
00044   else
00045     result = (this->get_host_addr (hoststr, MAXHOSTNAMELEN+1) != 0);
00046 
00047   if (!result)
00048     return -1;
00049 
00050   size_t total_len =
00051     ACE_OS::strlen (hoststr)
00052     + 5 // ACE_OS::strlen ("65535"), Assuming the max port number.
00053     + 1 // sizeof (':'), addr/port sep
00054     + 1; // sizeof ('\0'), terminating NUL
00055 #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
00056   ACE_TCHAR const *format = ACE_TEXT("%ls:%d");
00057 #else
00058   ACE_TCHAR const *format = ACE_TEXT("%s:%d");
00059 #endif /* !ACE_WIN32 && ACE_USES_WCHAR */
00060 #if defined (ACE_HAS_IPV6)
00061   if (ACE_OS::strchr (hoststr, ACE_TEXT (':')) != 0)
00062     {
00063       total_len += 2; // ACE_OS::strlen ("[]") IPv6 addr frames
00064 #  if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
00065       format = ACE_TEXT("[%ls]:%d");
00066 #  else
00067       format = ACE_TEXT("[%s]:%d");
00068 #  endif /* !ACE_WIN32 && ACE_USES_WCHAR */
00069     }
00070 #endif // ACE_HAS_IPV6
00071 
00072   if (size < total_len)
00073     return -1;
00074   else
00075       ACE_OS::sprintf (s, format,
00076                        ACE_TEXT_CHAR_TO_TCHAR (hoststr),
00077                        this->get_port_number ());
00078   return 0;
00079 }
00080 
00081 void
00082 ACE_INET_Addr::dump (void) const
00083 {
00084 #if defined (ACE_HAS_DUMP)
00085   ACE_TRACE ("ACE_INET_Addr::dump");
00086 
00087   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00088 
00089   ACE_TCHAR s[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16];
00090   this->addr_to_string(s, ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16);
00091   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%s"), s));
00092   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00093 #endif /* ACE_HAS_DUMP */
00094 }
00095 
00096 // Compare two addresses for inequality.
00097 
00098 bool
00099 ACE_INET_Addr::operator != (const ACE_INET_Addr &sap) const
00100 {
00101   ACE_TRACE ("ACE_INET_Addr::operator !=");
00102   return !((*this) == sap);
00103 }
00104 
00105 // Compare two addresses for equality.
00106 
00107 bool
00108 ACE_INET_Addr::operator == (const ACE_INET_Addr &sap) const
00109 {
00110   ACE_TRACE ("ACE_INET_Addr::operator ==");
00111 
00112   if (this->get_type () != sap.get_type ()
00113       || this->get_size () != sap.get_size ())
00114     return false;
00115 
00116   return (ACE_OS::memcmp (&this->inet_addr_,
00117                           &sap.inet_addr_,
00118                           this->get_size ()) == 0);
00119 }
00120 
00121 bool
00122 ACE_INET_Addr::is_ip_equal (const ACE_INET_Addr &sap) const
00123 {
00124     if (this->get_type () != sap.get_type ()
00125       || this->get_size () != sap.get_size ())
00126     return false;
00127 
00128 #if defined (ACE_HAS_IPV6)
00129   if (this->get_type () == PF_INET6)
00130     {
00131       const unsigned int *addr =
00132         reinterpret_cast<const unsigned int*>(this->ip_addr_pointer());
00133       const unsigned int *saddr =
00134         reinterpret_cast<const unsigned int*>(sap.ip_addr_pointer());
00135       return (addr[0] == saddr[0] &&
00136               addr[1] == saddr[1] &&
00137               addr[2] == saddr[2] &&
00138               addr[3] == saddr[3]);
00139     }
00140   else
00141 #endif /* ACE_HAS_IPV6 */
00142   return this->get_ip_address () == sap.get_ip_address();
00143 }
00144 
00145 
00146 u_long
00147 ACE_INET_Addr::hash (void) const
00148 {
00149 #if defined (ACE_HAS_IPV6)
00150   if (this->get_type () == PF_INET6)
00151     {
00152       const unsigned int *addr = (const unsigned int*)this->ip_addr_pointer();
00153       return addr[0] + addr[1] + addr[2] + addr[3] + this->get_port_number();
00154     }
00155   else
00156 #endif /* ACE_HAS_IPV6 */
00157   return this->get_ip_address () + this->get_port_number ();
00158 }
00159 
00160 ACE_INET_Addr::ACE_INET_Addr (void)
00161   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00162 {
00163   // ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00164   this->reset ();
00165 }
00166 
00167 int
00168 ACE_INET_Addr::set (const ACE_INET_Addr &sa)
00169 {
00170   ACE_TRACE ("ACE_INET_Addr::set");
00171 
00172   if (sa.get_type () == AF_ANY)
00173     // Ugh, this is really a base class, so don't copy it.
00174     ACE_OS::memset (&this->inet_addr_, 0, sizeof (this->inet_addr_));
00175   else
00176     {
00177       // It's ok to make the copy.
00178       ACE_OS::memcpy (&this->inet_addr_,
00179                       &sa.inet_addr_,
00180                       sa.get_size ());
00181 
00182       this->set_type (sa.get_type());
00183       this->set_size (sa.get_size());
00184     }
00185 
00186   return 0;
00187 }
00188 
00189 // Transform the string into the current addressing format.
00190 
00191 int
00192 ACE_INET_Addr::string_to_addr (const char s[], int address_family)
00193 {
00194   ACE_TRACE ("ACE_INET_Addr::string_to_addr");
00195   int result;
00196   char *ip_buf = 0;
00197   char *ip_addr = 0;
00198 
00199   // Need to make a duplicate since we'll be overwriting the string.
00200   ACE_ALLOCATOR_RETURN (ip_buf,
00201                         ACE_OS::strdup (s),
00202                         -1);
00203   ip_addr = ip_buf;
00204   // We use strrchr because of IPv6 addresses.
00205   char *port_p = ACE_OS::strrchr (ip_addr, ':');
00206 #if defined (ACE_HAS_IPV6)
00207   // Check for extended IPv6 format : '[' <ipv6 address> ']' ':' <port>
00208   if (ip_addr[0] == '[')
00209     {
00210       // find closing bracket
00211       char *cp_pos = ACE_OS::strchr (ip_addr, ']');
00212       // check for port separator after closing bracket
00213       // if not found leave it, error will come later
00214       if (cp_pos)
00215         {
00216           *cp_pos = '\0'; // blank out ']'
00217           ++ip_addr; // skip over '['
00218           if (cp_pos[1] == ':')
00219             port_p = cp_pos + 1;
00220           else
00221             port_p = cp_pos; // leads to error on missing port
00222         }
00223     }
00224 #endif /* ACE_HAS_IPV6 */
00225 
00226   if (port_p == 0) // Assume it's a port number.
00227     {
00228       char *endp = 0;
00229       u_short port =
00230         static_cast<u_short> (ACE_OS::strtol (ip_addr, &endp, 10));
00231       if (*endp == '\0')    // strtol scanned the entire string - all digits
00232         result = this->set (port, ACE_UINT32 (INADDR_ANY));
00233       else // port name
00234         result = this->set (ip_addr, ACE_UINT32 (INADDR_ANY));
00235     }
00236   else
00237     {
00238       *port_p = '\0'; ++port_p; // skip over ':'
00239 
00240       char *endp = 0;
00241       u_short port = static_cast<u_short> (ACE_OS::strtol (port_p, &endp, 10));
00242       if (*endp == '\0')    // strtol scanned the entire string - all digits
00243         result = this->set (port, ip_addr, 1, address_family);
00244       else
00245         result = this->set (port_p, ip_addr);
00246     }
00247 
00248   ACE_OS::free (ACE_MALLOC_T (ip_buf));
00249   return result;
00250 }
00251 
00252 int
00253 ACE_INET_Addr::set (const char address[], int address_family)
00254 {
00255   ACE_TRACE ("ACE_INET_Addr::set");
00256   return this->string_to_addr (address, address_family);
00257 }
00258 
00259 ACE_INET_Addr::ACE_INET_Addr (const char address[], int address_family)
00260   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00261 {
00262   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00263   this->reset ();
00264   this->set (address, address_family);
00265 }
00266 
00267 #if defined (ACE_HAS_WCHAR)
00268 ACE_INET_Addr::ACE_INET_Addr (const wchar_t address[], int address_family)
00269   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00270 {
00271   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00272   this->reset ();
00273   this->set (address, address_family);
00274 }
00275 
00276 #endif /* ACE_HAS_WCHAR */
00277 
00278 // Copy constructor.
00279 
00280 ACE_INET_Addr::ACE_INET_Addr (const ACE_INET_Addr &sa)
00281   : ACE_Addr (sa.get_type (), sa.get_size())
00282 {
00283   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00284   this->reset ();
00285   this->set (sa);
00286 }
00287 
00288 // Initializes a ACE_INET_Addr from a PORT_NUMBER and a 32 bit Internet
00289 // address.
00290 
00291 int
00292 ACE_INET_Addr::set (u_short port_number,
00293                     ACE_UINT32 inet_address,
00294                     int encode,
00295                     int map)
00296 {
00297   ACE_TRACE ("ACE_INET_Addr::set");
00298   this->set_address (reinterpret_cast<const char *> (&inet_address),
00299                      sizeof inet_address,
00300                      encode, map);
00301   this->set_port_number (port_number, encode);
00302 
00303   return 0;
00304 }
00305 
00306 
00307 // Initializes a ACE_INET_Addr from a PORT_NUMBER and the remote
00308 // HOST_NAME.
00309 
00310 int
00311 ACE_INET_Addr::set (u_short port_number,
00312                     const char host_name[],
00313                     int encode,
00314                     int address_family)
00315 {
00316   ACE_TRACE ("ACE_INET_Addr::set");
00317 
00318   // Yow, someone gave us a NULL host_name!
00319   if (host_name == 0)
00320     {
00321       errno = EINVAL;
00322       return -1;
00323     }
00324 
00325   ACE_OS::memset ((void *) &this->inet_addr_,
00326                   0,
00327                   sizeof this->inet_addr_);
00328 
00329 #if defined (ACE_HAS_IPV6)
00330   struct addrinfo hints;
00331   struct addrinfo *res = 0;
00332   int error = 0;
00333   ACE_OS::memset (&hints, 0, sizeof (hints));
00334 # if defined (ACE_USES_IPV4_IPV6_MIGRATION)
00335   if (address_family == AF_UNSPEC && !ACE::ipv6_enabled())
00336     address_family = AF_INET;
00337 # endif /* ACE_USES_IPV4_IPV6_MIGRATION */
00338   if (address_family == AF_UNSPEC || address_family == AF_INET6)
00339     {
00340       hints.ai_family = AF_INET6;
00341       error = ::getaddrinfo (host_name, 0, &hints, &res);
00342       if (error)
00343         {
00344           if (address_family == AF_INET6)
00345             {
00346               if (res)
00347                 ::freeaddrinfo(res);
00348               return -1;
00349             }
00350           address_family = AF_INET;
00351         }
00352     }
00353   if (address_family == AF_INET)
00354     {
00355       hints.ai_family = AF_INET;
00356       error = ::getaddrinfo (host_name, 0, &hints, &res);
00357       if (error)
00358         {
00359           if (res)
00360             ::freeaddrinfo(res);
00361           return -1;
00362         }
00363     }
00364   this->set_type (res->ai_family);
00365   this->set_addr (res->ai_addr, res->ai_addrlen);
00366   this->set_port_number (port_number, encode);
00367   ::freeaddrinfo (res);
00368   return 0;
00369 #else /* ACE_HAS_IPV6 */
00370 
00371   // IPv6 not supported... insure the family is set to IPv4
00372   address_family = AF_INET;
00373   this->set_type (address_family);
00374   this->inet_addr_.in4_.sin_family = static_cast<short> (address_family);
00375   struct in_addr addrv4;
00376   if (ACE_OS::inet_aton (host_name,
00377                          &addrv4) == 1)
00378     return this->set (port_number,
00379                       encode ? ACE_NTOHL (addrv4.s_addr) : addrv4.s_addr,
00380                       encode);
00381   else
00382     {
00383 #  if defined (ACE_VXWORKS) && defined (ACE_LACKS_GETHOSTBYNAME)
00384       hostent *hp = ACE_OS::gethostbyname (host_name);
00385 #  else
00386       hostent hentry;
00387       ACE_HOSTENT_DATA buf;
00388       int h_error;  // Not the same as errno!
00389 
00390       hostent *hp = ACE_OS::gethostbyname_r (host_name, &hentry,
00391                                              buf, &h_error);
00392 #  endif /* ACE_VXWORKS */
00393 
00394       if (hp == 0)
00395         {
00396           return -1;
00397         }
00398       else
00399         {
00400           (void) ACE_OS::memcpy ((void *) &addrv4.s_addr,
00401                                  hp->h_addr,
00402                                  hp->h_length);
00403           return this->set (port_number,
00404                             encode ? ACE_NTOHL (addrv4.s_addr) : addrv4.s_addr,
00405                             encode);
00406         }
00407     }
00408 #endif /* ACE_HAS_IPV6 */
00409 }
00410 
00411 // Helper function to get a port number from a port name.
00412 
00413 static int get_port_number_from_name (const char port_name[],
00414                                       const char protocol[])
00415 {
00416   int port_number = 0;
00417 
00418   // Maybe port_name is directly a port number?
00419   char *endp = 0;
00420   port_number = static_cast<int> (ACE_OS::strtol (port_name, &endp, 10));
00421 
00422   if (port_number >= 0 && *endp == '\0')
00423     {
00424       // Ok, port_name was really a number, and nothing else.  We
00425       // store that value as the port number.  NOTE: this number must
00426       // be returned in network byte order!
00427       u_short n = static_cast<u_short> (port_number);
00428       n = ACE_HTONS (n);
00429       return n;
00430     }
00431 
00432   // We try to resolve port number from its name.
00433 
00434 #if defined (ACE_LACKS_GETSERVBYNAME)
00435   port_number = 0;
00436   ACE_UNUSED_ARG (port_name);
00437   ACE_UNUSED_ARG (protocol);
00438 #else
00439   port_number = -1;
00440   servent sentry;
00441   ACE_SERVENT_DATA buf;
00442   servent *sp = ACE_OS::getservbyname_r (port_name,
00443                                          protocol,
00444                                          &sentry,
00445                                          buf);
00446   if (sp != 0)
00447     port_number = sp->s_port;
00448 #endif /* ACE_LACKS_GETSERVBYNAME */
00449 
00450   return port_number;
00451 }
00452 
00453 // Initializes a ACE_INET_Addr from a <port_name> and the remote
00454 // <host_name>.
00455 
00456 int
00457 ACE_INET_Addr::set (const char port_name[],
00458                     const char host_name[],
00459                     const char protocol[])
00460 {
00461   ACE_TRACE ("ACE_INET_Addr::set");
00462 
00463   int port_number = get_port_number_from_name (port_name, protocol);
00464   if (port_number == -1)
00465     {
00466       ACE_UNUSED_ARG (host_name);
00467       ACE_NOTSUP_RETURN (-1);
00468     }
00469 
00470   int address_family = PF_UNSPEC;
00471 #  if defined (ACE_HAS_IPV6)
00472   if (ACE_OS::strcmp (ACE_TEXT_CHAR_TO_TCHAR(protocol), ACE_TEXT ("tcp6")) == 0)
00473     address_family = AF_INET6;
00474 #  endif /* ACE_HAS_IPV6 */
00475 
00476   return this->set (static_cast<u_short> (port_number),
00477                     host_name, 0, address_family);
00478 }
00479 
00480 // Initializes a ACE_INET_Addr from a <port_name> and a 32 bit
00481 // Internet address.
00482 
00483 int
00484 ACE_INET_Addr::set (const char port_name[],
00485                     ACE_UINT32 inet_address,
00486                     const char protocol[])
00487 {
00488   ACE_TRACE ("ACE_INET_Addr::set");
00489 
00490   int const port_number = get_port_number_from_name (port_name, protocol);
00491   if (port_number == -1)
00492     {
00493       ACE_UNUSED_ARG (inet_address);
00494       ACE_NOTSUP_RETURN (-1);
00495     }
00496 
00497   return this->set (static_cast<u_short> (port_number),
00498                     inet_address, 0);
00499 }
00500 
00501 // Creates a ACE_INET_Addr from a PORT_NUMBER and the remote
00502 // HOST_NAME.
00503 
00504 ACE_INET_Addr::ACE_INET_Addr (u_short port_number,
00505                               const char host_name[],
00506                               int address_family)
00507   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00508 {
00509   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00510   ACE_OS::memset (&this->inet_addr_, 0, sizeof (this->inet_addr_));
00511   if (this->set (port_number,
00512                  host_name,
00513                  1,
00514                  address_family) == -1)
00515     ACE_ERROR ((LM_ERROR,
00516                 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr: %p\n"),
00517                 ACE_TEXT_CHAR_TO_TCHAR ((host_name == 0) ?
00518                                         "<unknown>" : host_name)));
00519 }
00520 
00521 #if defined (ACE_HAS_WCHAR)
00522 ACE_INET_Addr::ACE_INET_Addr (u_short port_number,
00523                               const wchar_t host_name[],
00524                               int address_family)
00525   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00526 {
00527   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00528   ACE_OS::memset (&this->inet_addr_, 0, sizeof (this->inet_addr_));
00529   if (this->set (port_number,
00530                  host_name,
00531                  1,
00532                  address_family) == -1)
00533     ACE_ERROR ((LM_ERROR,
00534                 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr: %p\n"),
00535                 ACE_TEXT_WCHAR_TO_TCHAR ((host_name == 0) ?
00536                                          ACE_TEXT_WIDE ("<unknown>") :
00537                                          host_name)));
00538 }
00539 #endif /* ACE_HAS_WCHAR */
00540 
00541 // Creates a ACE_INET_Addr from a sockaddr_in structure.
00542 
00543 int
00544 ACE_INET_Addr::set (const sockaddr_in *addr, int len)
00545 {
00546   ACE_TRACE ("ACE_INET_Addr::set");
00547 
00548   if (addr->sin_family == AF_INET)
00549     {
00550       int maxlen = static_cast<int> (sizeof (this->inet_addr_.in4_));
00551       if (len > maxlen)
00552         len = maxlen;
00553       ACE_OS::memcpy (&this->inet_addr_.in4_, addr, len);
00554       this->base_set (AF_INET, len);
00555       return 0;
00556     }
00557 #if defined (ACE_HAS_IPV6)
00558   else if (addr->sin_family == AF_INET6)
00559     {
00560       int maxlen = static_cast<int> (sizeof (this->inet_addr_.in6_));
00561       if (len > maxlen)
00562         len = maxlen;
00563       ACE_OS::memcpy (&this->inet_addr_.in6_, addr, len);
00564       this->base_set (AF_INET6, len);
00565       return 0;
00566     }
00567 #endif /* ACE_HAS_IPV6 */
00568 
00569   errno = EAFNOSUPPORT;
00570   return -1;
00571 }
00572 
00573 // Return the address.
00574 
00575 void *
00576 ACE_INET_Addr::get_addr (void) const
00577 {
00578   ACE_TRACE ("ACE_INET_Addr::get_addr");
00579   return (void*)&this->inet_addr_;
00580 }
00581 
00582 void
00583 ACE_INET_Addr::set_addr (void *addr, int len)
00584 {
00585   this->set_addr (addr, len, 0);
00586 }
00587 
00588 // Set a pointer to the address.
00589 void
00590 ACE_INET_Addr::set_addr (void *addr, int /* len */, int map)
00591 {
00592   ACE_TRACE ("ACE_INET_Addr::set_addr");
00593   struct sockaddr_in *getfamily = static_cast<struct sockaddr_in *> (addr);
00594 
00595   if (getfamily->sin_family == AF_INET)
00596     {
00597 #if defined (ACE_HAS_IPV6)
00598       if (map)
00599         this->set_type (AF_INET6);
00600       else
00601 #endif /* ACE_HAS_IPV6 */
00602         this->set_type (AF_INET);
00603       this->set_port_number (getfamily->sin_port, 0);
00604       this->set_address (reinterpret_cast<const char*> (&getfamily->sin_addr),
00605                          sizeof (getfamily->sin_addr),
00606                          0, map);
00607     }
00608 #if defined (ACE_HAS_IPV6)
00609   else if (getfamily->sin_family == AF_INET6)
00610     {
00611       struct sockaddr_in6 *in6 = static_cast<struct sockaddr_in6*> (addr);
00612       this->set_port_number (in6->sin6_port, 0);
00613       this->set_address (reinterpret_cast<const char*> (&in6->sin6_addr),
00614                          sizeof (in6->sin6_addr),
00615                          0);
00616       this->inet_addr_.in6_.sin6_scope_id = in6->sin6_scope_id;
00617     }
00618 #endif // ACE_HAS_IPV6
00619 }
00620 
00621 // Creates a ACE_INET_Addr from a sockaddr_in structure.
00622 
00623 ACE_INET_Addr::ACE_INET_Addr (const sockaddr_in *addr, int len)
00624   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00625 {
00626   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00627   this->reset ();
00628   this->set (addr, len);
00629 }
00630 
00631 // Creates a ACE_INET_Addr from a PORT_NUMBER and an Internet address.
00632 
00633 ACE_INET_Addr::ACE_INET_Addr (u_short port_number,
00634                               ACE_UINT32 inet_address)
00635   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00636 {
00637   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00638   this->reset ();
00639   if (this->set (port_number, inet_address) == -1)
00640     ACE_ERROR ((LM_ERROR,
00641                 ACE_TEXT ("%p\n"),
00642                 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr")));
00643 }
00644 
00645 // Creates a ACE_INET_Addr from a PORT_NAME and the remote
00646 // HOST_NAME.
00647 
00648 ACE_INET_Addr::ACE_INET_Addr (const char port_name[],
00649                               const char host_name[],
00650                               const char protocol[])
00651   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00652 {
00653   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00654   this->reset ();
00655   if (this->set (port_name,
00656                  host_name,
00657                  protocol) == -1)
00658     ACE_ERROR ((LM_ERROR,
00659                 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr")));
00660 }
00661 
00662 #if defined (ACE_HAS_WCHAR)
00663 ACE_INET_Addr::ACE_INET_Addr (const wchar_t port_name[],
00664                               const wchar_t host_name[],
00665                               const wchar_t protocol[])
00666   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00667 {
00668   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00669   this->reset ();
00670   if (this->set (port_name,
00671                  host_name,
00672                  protocol) == -1)
00673     ACE_ERROR ((LM_ERROR,
00674                 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr")));
00675 }
00676 #endif /* ACE_HAS_WCHAR */
00677 
00678 // Creates a ACE_INET_Addr from a PORT_NAME and an Internet address.
00679 
00680 ACE_INET_Addr::ACE_INET_Addr (const char port_name[],
00681                               ACE_UINT32 inet_address,
00682                               const char protocol[])
00683   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00684 {
00685   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00686 #if !defined (ACE_LACKS_HTONL)
00687   this->reset ();
00688   if (this->set (port_name,
00689                  htonl (inet_address),
00690                  protocol) == -1)
00691     ACE_ERROR ((LM_ERROR,
00692                 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr")));
00693 #else
00694   ACE_UNUSED_ARG (port_name);
00695   ACE_UNUSED_ARG (inet_address);
00696   ACE_UNUSED_ARG (protocol);
00697 #endif
00698 }
00699 
00700 #if defined (ACE_HAS_WCHAR)
00701 ACE_INET_Addr::ACE_INET_Addr (const wchar_t port_name[],
00702                               ACE_UINT32 inet_address,
00703                               const wchar_t protocol[])
00704   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00705 {
00706   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00707 #if !defined (ACE_LACKS_HTONL)
00708   this->reset ();
00709   if (this->set (port_name,
00710                  htonl (inet_address),
00711                  protocol) == -1)
00712     ACE_ERROR ((LM_ERROR,
00713                 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr")));
00714 #else
00715   ACE_UNUSED_ARG (port_name);
00716   ACE_UNUSED_ARG (inet_address);
00717   ACE_UNUSED_ARG (protocol);
00718 #endif
00719 }
00720 #endif /* ACE_HAS_WCHAR */
00721 
00722 ACE_INET_Addr::~ACE_INET_Addr (void)
00723 {
00724 }
00725 
00726 int
00727 ACE_INET_Addr::get_host_name (char hostname[],
00728                               size_t len) const
00729 {
00730   ACE_TRACE ("ACE_INET_Addr::get_host_name");
00731 
00732   int result;
00733   if (len > 1)
00734     {
00735       result = get_host_name_i (hostname,len);
00736       if (result < 0)
00737         {
00738           if (result == -2)
00739             // We know that hostname is nul-terminated
00740             result = -1;
00741           else
00742             {
00743               //result == -1;
00744               // This could be worse than hostname[len -1] = '\0'?
00745               hostname[0] = '\0';
00746             }
00747         }
00748     }
00749   else
00750     {
00751       if (len == 1)
00752         hostname[0] = '\0';
00753       result = -1;
00754     }
00755 
00756   return result;
00757 }
00758 
00759 #if defined (ACE_HAS_WCHAR)
00760 int
00761 ACE_INET_Addr::get_host_name (wchar_t hostname[],
00762                               size_t len) const
00763 {
00764   ACE_TRACE ("ACE_INET_Addr::get_host_name");
00765 
00766   char char_hostname [MAXHOSTNAMELEN + 1];
00767 
00768   // We have a build in limitation of MAXHOSTNAMELEN
00769   if (len > MAXHOSTNAMELEN + 1)
00770     len = MAXHOSTNAMELEN + 1;
00771 
00772   // Call the char version
00773   int result = this->get_host_name (char_hostname, len);
00774 
00775   // And copy it over, if successful
00776   if (result == 0)
00777     ACE_OS::strcpy (hostname,
00778                     ACE_Ascii_To_Wide (char_hostname).wchar_rep ());
00779 
00780   return result;
00781 }
00782 #endif /* ACE_HAS_WCHAR */
00783 
00784 // Return the character representation of the hostname.
00785 
00786 const char *
00787 ACE_INET_Addr::get_host_name (void) const
00788 {
00789   ACE_TRACE ("ACE_INET_Addr::get_host_name");
00790 
00791   static char name[MAXHOSTNAMELEN + 1];
00792   if (this->get_host_name (name, MAXHOSTNAMELEN + 1) == -1)
00793     ACE_OS::strcpy (name, "<unknown>");
00794   return name;
00795 }
00796 
00797 void
00798 ACE_INET_Addr::set_port_number (u_short port_number,
00799                                 int encode)
00800 {
00801   ACE_TRACE ("ACE_INET_Addr::set_port_number");
00802 
00803   if (encode)
00804     port_number = ACE_HTONS (port_number);
00805 
00806 #if defined (ACE_HAS_IPV6)
00807   if (this->get_type () == AF_INET6)
00808     this->inet_addr_.in6_.sin6_port = port_number;
00809   else
00810 #endif /* ACE_HAS_IPV6 */
00811   this->inet_addr_.in4_.sin_port = port_number;
00812 }
00813 
00814 // returns -2 when the hostname is truncated
00815 int
00816 ACE_INET_Addr::get_host_name_i (char hostname[], size_t len) const
00817 {
00818   ACE_TRACE ("ACE_INET_Addr::get_host_name_i");
00819 
00820 #if defined (ACE_HAS_IPV6)
00821   if ((this->get_type () == PF_INET6 &&
00822        0 == ACE_OS::memcmp (&this->inet_addr_.in6_.sin6_addr,
00823                             &in6addr_any,
00824                             sizeof (this->inet_addr_.in6_.sin6_addr)))
00825       ||
00826       (this->get_type () == PF_INET &&
00827        this->inet_addr_.in4_.sin_addr.s_addr == INADDR_ANY))
00828 #else
00829   if (this->inet_addr_.in4_.sin_addr.s_addr == INADDR_ANY)
00830 #endif /* ACE_HAS_IPV6 */
00831     {
00832       if (ACE_OS::hostname (hostname, len) == -1)
00833         return -1;
00834       else
00835         return 0;
00836     }
00837   else
00838     {
00839 #if defined (ACE_VXWORKS) && defined (ACE_LACKS_GETHOSTBYADDR)
00840       ACE_UNUSED_ARG (len);
00841       int error =
00842         ::hostGetByAddr ((int) this->inet_addr_.in4_.sin_addr.s_addr,
00843                          hostname);
00844       if (error == OK)
00845         return 0;
00846       else
00847         {
00848           errno = error;
00849           return -1;
00850         }
00851 #else
00852 #  if defined (DIGITAL_UNIX) && defined (__GNUC__)
00853       hostent *hp = ACE_OS::gethostbyaddr ((char *)this->ip_addr_pointer (),
00854                                            this->ip_addr_size (),
00855                                            this->get_type ());
00856 #  else
00857       int h_error;  // Not the same as errno!
00858       hostent hentry;
00859       ACE_HOSTENT_DATA buf;
00860       hostent *hp =
00861         ACE_OS::gethostbyaddr_r ((char *)this->ip_addr_pointer (),
00862                                  this->ip_addr_size (),
00863                                  this->get_type (),
00864                                  &hentry,
00865                                  buf,
00866                                  &h_error);
00867 #  endif /* DIGITAL_UNIX */
00868 
00869       if (hp == 0 || hp->h_name == 0)
00870         return -1;
00871 
00872       if (ACE_OS::strlen (hp->h_name) >= len)
00873         {
00874           // We know the length, so use memcpy
00875           if (len > 0)
00876             {
00877               ACE_OS::memcpy (hostname, hp->h_name, len - 1);
00878               hostname[len-1]= '\0';
00879             }
00880           errno = ENOSPC;
00881           return -2;  // -2 Means that we have a good string
00882           // Using errno looks ok, but ENOSPC could be set on
00883           // other places.
00884         }
00885 
00886       ACE_OS::strcpy (hostname, hp->h_name);
00887       return 0;
00888 #endif /* ACE_VXWORKS */
00889     }
00890 }
00891 
00892 int ACE_INET_Addr::set_address (const char *ip_addr,
00893                                 int len,
00894                                 int encode /* = 1 */,
00895                                 int map /* = 0 */)
00896 {
00897   ACE_TRACE ("ACE_INET_Addr::set_address");
00898   // This is really intended for IPv4. If the object is IPv4, or the type
00899   // hasn't been set but it's a 4-byte address, go ahead. If this is an
00900   // IPv6 object and <encode> is requested, refuse.
00901   if (encode && len != 4)
00902     {
00903       errno = EAFNOSUPPORT;
00904       return -1;
00905     }
00906 
00907   if (len == 4)
00908     {
00909       ACE_UINT32 ip4 = *reinterpret_cast<const ACE_UINT32 *> (ip_addr);
00910       if (encode)
00911         ip4 = ACE_HTONL (ip4);
00912 
00913 
00914       if (this->get_type () == AF_INET && map == 0) {
00915         this->base_set (AF_INET, sizeof (this->inet_addr_.in4_));
00916 #ifdef ACE_HAS_SOCKADDR_IN_SIN_LEN
00917         this->inet_addr_.in4_.sin_len = sizeof (this->inet_addr_.in4_);
00918 #endif
00919         this->inet_addr_.in4_.sin_family = AF_INET;
00920         this->set_size (sizeof (this->inet_addr_.in4_));
00921         ACE_OS::memcpy (&this->inet_addr_.in4_.sin_addr,
00922                         &ip4,
00923                         len);
00924       }
00925 #if defined (ACE_HAS_IPV6)
00926       else if (map == 0)
00927         {
00928           // this->set_type (AF_INET);
00929           this->base_set (AF_INET, sizeof (this->inet_addr_.in4_));
00930 #ifdef ACE_HAS_SOCKADDR_IN_SIN_LEN
00931           this->inet_addr_.in4_.sin_len = sizeof (this->inet_addr_.in4_);
00932 #endif
00933           this->inet_addr_.in4_.sin_family = AF_INET;
00934           this->set_size (sizeof (this->inet_addr_.in4_));
00935           ACE_OS::memcpy (&this->inet_addr_.in4_.sin_addr,
00936                           &ip4, len);
00937         }
00938       // If given an IPv4 address to copy to an IPv6 object, map it to
00939       // an IPv4-mapped IPv6 address.
00940       else
00941         {
00942           this->base_set (AF_INET6, sizeof (this->inet_addr_.in6_));
00943 #ifdef ACE_HAS_SOCKADDR_IN6_SIN6_LEN
00944           this->inet_addr_.in6_.sin6_len = sizeof (this->inet_addr_.in6_);
00945 #endif
00946           this->inet_addr_.in6_.sin6_family = AF_INET6;
00947           this->set_size (sizeof (this->inet_addr_.in6_));
00948           if (ip4 == INADDR_ANY)
00949             {
00950               in6_addr ip6 = in6addr_any;
00951               ACE_OS::memcpy (&this->inet_addr_.in6_.sin6_addr,
00952                               &ip6,
00953                               sizeof (ip6));
00954               return 0;
00955             }
00956 
00957           // RFC 3330 defines loopback as any address with 127.x.x.x
00958           if ((ip4 & 0XFF000000) == (INADDR_LOOPBACK & 0XFF000000))
00959             {
00960               in6_addr ip6 = in6addr_loopback;
00961               ACE_OS::memcpy (&this->inet_addr_.in6_.sin6_addr,
00962                               &ip6,
00963                               sizeof (ip6));
00964               return 0;
00965             }
00966 
00967           // Build up a 128 bit address.  An IPv4-mapped IPv6 address
00968           // is defined as 0:0:0:0:0:ffff:IPv4_address.  This is defined
00969           // in RFC 1884 */
00970           ACE_OS::memset (&this->inet_addr_.in6_.sin6_addr, 0, 16);
00971           this->inet_addr_.in6_.sin6_addr.s6_addr[10] =
00972             this->inet_addr_.in6_.sin6_addr.s6_addr[11] = 0xff;
00973           ACE_OS::memcpy
00974             (&this->inet_addr_.in6_.sin6_addr.s6_addr[12], &ip4, 4);
00975         }
00976 #endif /* ACE_HAS_IPV6 */
00977       return 0;
00978     }   /* end if (len == 4) */
00979 #if defined (ACE_HAS_IPV6)
00980   else if (len == 16)
00981     {
00982       if (this->get_type () != PF_INET6)
00983         {
00984           errno = EAFNOSUPPORT;
00985           return -1;
00986         }
00987       // We protect ourselves up above so IPv6 must be possible here.
00988       this->base_set (AF_INET6, sizeof (this->inet_addr_.in6_));
00989       this->inet_addr_.in6_.sin6_family = AF_INET6;
00990       ACE_OS::memcpy (&this->inet_addr_.in6_.sin6_addr, ip_addr, len);
00991 
00992       return 0;
00993     } /* end len == 16 */
00994 #endif /* ACE_HAS_IPV6 */
00995 
00996   // Here with an unrecognized length.
00997   errno = EAFNOSUPPORT;
00998   return -1;
00999 
01000 }
01001 
01002 #if (defined (__linux__) || defined (ACE_WIN32)) && defined (ACE_HAS_IPV6)
01003 int
01004 ACE_INET_Addr::set_interface (const char *intf_name)
01005 {
01006   if (this->get_type () == PF_INET6 &&
01007       (IN6_IS_ADDR_LINKLOCAL (&this->inet_addr_.in6_.sin6_addr) ||
01008        IN6_IS_ADDR_MC_LINKLOCAL (&this->inet_addr_.in6_.sin6_addr)))
01009     {
01010 #if defined (__linux__)
01011       this->inet_addr_.in6_.sin6_scope_id =
01012         ACE_OS::if_nametoindex (intf_name);
01013 #else
01014       this->inet_addr_.in6_.sin6_scope_id =
01015         intf_name ? ACE_OS::atoi (intf_name) : 0;
01016 #endif
01017       // check to see if the interface lookup succeeded
01018       if (this->inet_addr_.in6_.sin6_scope_id != 0)
01019         return 0;
01020       else
01021         return -1;
01022     }
01023   else
01024     return 0;
01025 
01026 }
01027 #endif /* __linux && ACE_HAS_IPV6 */
01028 
01029 const char *
01030 ACE_INET_Addr::get_host_addr (char *dst, int size) const
01031 {
01032 #if defined (ACE_HAS_IPV6)
01033   if (this->get_type () == AF_INET6)
01034     {
01035       // mcorino@remedy.nl - Aug-26, 2005
01036       // I don't think this should be done because it results in a decimal address
01037       // representation which is not distinguishable from the IPv4 form which makes
01038       // it impossible to resolve back to an IPv6 INET_Addr without prior knowledge
01039       // that this was such an address to begin with.
01040 
01041       //if (IN6_IS_ADDR_V4MAPPED (&this->inet_addr_.in6_.sin6_addr))
01042       //{
01043       //  ACE_UINT32 addr;
01044       //  addr = this->get_ip_address();
01045       //  addr = ACE_HTONL (addr);
01046       //  return ACE_OS::inet_ntop (AF_INET, &addr, dst, size);
01047       //}
01048 
01049 #  if defined (ACE_WIN32)
01050       if (0 == ::getnameinfo (reinterpret_cast<const sockaddr*> (&this->inet_addr_.in6_),
01051                               this->get_size (),
01052                               dst,
01053                               size,
01054                               0, 0,    // Don't want service name
01055                               NI_NUMERICHOST))
01056         return dst;
01057       ACE_OS::set_errno_to_wsa_last_error ();
01058       return 0;
01059 #  else
01060       const char *ch = ACE_OS::inet_ntop (AF_INET6,
01061                                           &this->inet_addr_.in6_.sin6_addr,
01062                                           dst,
01063                                           size);
01064 #if defined (__linux__)
01065       if ((IN6_IS_ADDR_LINKLOCAL (&this->inet_addr_.in6_.sin6_addr) ||
01066            IN6_IS_ADDR_MC_LINKLOCAL (&this->inet_addr_.in6_.sin6_addr)) &&
01067           this->inet_addr_.in6_.sin6_scope_id != 0)
01068         {
01069           char scope_buf[32];
01070           ACE_OS::sprintf (scope_buf, "%%%u", this->inet_addr_.in6_.sin6_scope_id);
01071           if ((ACE_OS::strlen (ch)+ACE_OS::strlen (scope_buf)) < (size_t)size)
01072             {
01073               ACE_OS::strcat (dst, scope_buf);
01074             }
01075         }
01076 #endif
01077       return ch;
01078 #  endif /* ACE_WIN32 */
01079     }
01080 #endif /* ACE_HAS_IPV6 */
01081 
01082 #if defined (ACE_VXWORKS)
01083   ACE_UNUSED_ARG (dst);
01084   ACE_UNUSED_ARG (size);
01085 
01086   // It would be nice to be able to encapsulate this into
01087   // ACE_OS::inet_ntoa(), but that would lead to either inefficiencies
01088   // on vxworks or lack of thread safety.
01089   //
01090   // So, we use the way that vxworks suggests.
01091   ACE_INET_Addr *ncthis = const_cast<ACE_INET_Addr *> (this);
01092   inet_ntoa_b(this->inet_addr_.in4_.sin_addr, ncthis->buf_);
01093   ACE_OS::strsncpy (dst, &buf_[0], size);
01094   return &buf_[0];
01095 #else /* ACE_VXWORKS */
01096   char *ch = ACE_OS::inet_ntoa (this->inet_addr_.in4_.sin_addr);
01097   ACE_OS::strsncpy (dst, ch, size);
01098   return ch;
01099 #endif
01100 }
01101 
01102 // Return the dotted Internet address.
01103 const char *
01104 ACE_INET_Addr::get_host_addr (void) const
01105 {
01106   ACE_TRACE ("ACE_INET_Addr::get_host_addr");
01107 #if defined (ACE_HAS_IPV6)
01108   static char buf[INET6_ADDRSTRLEN];
01109   return this->get_host_addr (buf, INET6_ADDRSTRLEN);
01110 #else /* ACE_HAS_IPV6 */
01111 #  if defined (ACE_VXWORKS)
01112   // It would be nice to be able to encapsulate this into
01113   // ACE_OS::inet_ntoa(), but that would lead to either inefficiencies
01114   // on vxworks or lack of thread safety.
01115   //
01116   // So, we use the way that vxworks suggests.
01117   ACE_INET_Addr *ncthis = const_cast<ACE_INET_Addr *> (this);
01118   inet_ntoa_b (this->inet_addr_.in4_.sin_addr, ncthis->buf_);
01119   return &buf_[0];
01120 #  else /* ACE_VXWORKS */
01121   return ACE_OS::inet_ntoa (this->inet_addr_.in4_.sin_addr);
01122 #  endif /* !ACE_VXWORKS */
01123 #endif /* !ACE_HAS_IPV6 */
01124 }
01125 
01126 // Return the 4-byte IP address, converting it into host byte order.
01127 ACE_UINT32
01128 ACE_INET_Addr::get_ip_address (void) const
01129 {
01130   ACE_TRACE ("ACE_INET_Addr::get_ip_address");
01131 #if defined (ACE_HAS_IPV6)
01132   if (this->get_type () == AF_INET6)
01133     {
01134       if (IN6_IS_ADDR_V4MAPPED (&this->inet_addr_.in6_.sin6_addr) ||
01135           IN6_IS_ADDR_V4COMPAT (&this->inet_addr_.in6_.sin6_addr)    )
01136         {
01137           ACE_UINT32 addr;
01138           // Return the last 32 bits of the address
01139           char *thisaddrptr = (char*)this->ip_addr_pointer ();
01140           thisaddrptr += 128/8 - 32/8;
01141           ACE_OS::memcpy (&addr, thisaddrptr, sizeof (addr));
01142           return ACE_NTOHL (addr);
01143         }
01144 
01145       ACE_ERROR ((LM_ERROR,
01146                   ACE_TEXT ("ACE_INET_Addr::get_ip_address: address is a IPv6 address not IPv4\n")));
01147       errno = EAFNOSUPPORT;
01148       return 0;
01149     }
01150 #endif /* ACE_HAS_IPV6 */
01151   return ACE_NTOHL (ACE_UINT32 (this->inet_addr_.in4_.sin_addr.s_addr));
01152 }
01153 
01154 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Sun Jan 27 12:05:28 2008 for ACE by doxygen 1.3.6