INET_Addr.cpp

Go to the documentation of this file.
00001 // $Id: INET_Addr.cpp 81082 2008-03-25 09:09:11Z johnnyw $
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 81082 2008-03-25 09:09:11Z johnnyw $")
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       long port = ACE_OS::strtol (ip_addr, &endp, 10);
00230 
00231       if (*endp == '\0')    // strtol scanned the entire string - all digits
00232         {
00233           if (port < 0 || port > ACE_MAX_DEFAULT_PORT)
00234             result = -1;
00235           else
00236             result = this->set (u_short (port), ACE_UINT32 (INADDR_ANY));
00237         }
00238       else // port name
00239         result = this->set (ip_addr, ACE_UINT32 (INADDR_ANY));
00240     }
00241   else
00242     {
00243       *port_p = '\0'; ++port_p; // skip over ':'
00244 
00245       char *endp = 0;
00246       long port = ACE_OS::strtol (port_p, &endp, 10);
00247 
00248       if (*endp == '\0')    // strtol scanned the entire string - all digits
00249         {
00250           if (port < 0 || port > ACE_MAX_DEFAULT_PORT)
00251             result = -1;
00252           else
00253             result = this->set (u_short (port), ip_addr, 1, address_family);
00254         }
00255       else
00256         result = this->set (port_p, ip_addr);
00257     }
00258 
00259   ACE_OS::free (ACE_MALLOC_T (ip_buf));
00260   return result;
00261 }
00262 
00263 int
00264 ACE_INET_Addr::set (const char address[], int address_family)
00265 {
00266   ACE_TRACE ("ACE_INET_Addr::set");
00267   return this->string_to_addr (address, address_family);
00268 }
00269 
00270 ACE_INET_Addr::ACE_INET_Addr (const char address[], int address_family)
00271   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00272 {
00273   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00274   this->reset ();
00275   this->set (address, address_family);
00276 }
00277 
00278 #if defined (ACE_HAS_WCHAR)
00279 ACE_INET_Addr::ACE_INET_Addr (const wchar_t address[], int address_family)
00280   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00281 {
00282   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00283   this->reset ();
00284   this->set (address, address_family);
00285 }
00286 
00287 #endif /* ACE_HAS_WCHAR */
00288 
00289 // Copy constructor.
00290 
00291 ACE_INET_Addr::ACE_INET_Addr (const ACE_INET_Addr &sa)
00292   : ACE_Addr (sa.get_type (), sa.get_size())
00293 {
00294   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00295   this->reset ();
00296   this->set (sa);
00297 }
00298 
00299 // Initializes a ACE_INET_Addr from a PORT_NUMBER and a 32 bit Internet
00300 // address.
00301 
00302 int
00303 ACE_INET_Addr::set (u_short port_number,
00304                     ACE_UINT32 inet_address,
00305                     int encode,
00306                     int map)
00307 {
00308   ACE_TRACE ("ACE_INET_Addr::set");
00309   this->set_address (reinterpret_cast<const char *> (&inet_address),
00310                      sizeof inet_address,
00311                      encode, map);
00312   this->set_port_number (port_number, encode);
00313 
00314   return 0;
00315 }
00316 
00317 
00318 // Initializes a ACE_INET_Addr from a PORT_NUMBER and the remote
00319 // HOST_NAME.
00320 
00321 int
00322 ACE_INET_Addr::set (u_short port_number,
00323                     const char host_name[],
00324                     int encode,
00325                     int address_family)
00326 {
00327   ACE_TRACE ("ACE_INET_Addr::set");
00328 
00329   // Yow, someone gave us a NULL host_name!
00330   if (host_name == 0)
00331     {
00332       errno = EINVAL;
00333       return -1;
00334     }
00335 
00336   ACE_OS::memset ((void *) &this->inet_addr_,
00337                   0,
00338                   sizeof this->inet_addr_);
00339 
00340 #if defined (ACE_HAS_IPV6)
00341   struct addrinfo hints;
00342   struct addrinfo *res = 0;
00343   int error = 0;
00344   ACE_OS::memset (&hints, 0, sizeof (hints));
00345 # if defined (ACE_USES_IPV4_IPV6_MIGRATION)
00346   if (address_family == AF_UNSPEC && !ACE::ipv6_enabled())
00347     address_family = AF_INET;
00348 # endif /* ACE_USES_IPV4_IPV6_MIGRATION */
00349   if (address_family == AF_UNSPEC || address_family == AF_INET6)
00350     {
00351       hints.ai_family = AF_INET6;
00352       error = ::getaddrinfo (host_name, 0, &hints, &res);
00353       if (error)
00354         {
00355           if (address_family == AF_INET6)
00356             {
00357               if (res)
00358                 ::freeaddrinfo(res);
00359               errno = error;
00360               return -1;
00361             }
00362           address_family = AF_INET;
00363         }
00364     }
00365   if (address_family == AF_INET)
00366     {
00367       hints.ai_family = AF_INET;
00368       error = ::getaddrinfo (host_name, 0, &hints, &res);
00369       if (error)
00370         {
00371           if (res)
00372             ::freeaddrinfo(res);
00373           errno = error;
00374           return -1;
00375         }
00376     }
00377   this->set_type (res->ai_family);
00378   this->set_addr (res->ai_addr, res->ai_addrlen);
00379   this->set_port_number (port_number, encode);
00380   ::freeaddrinfo (res);
00381   return 0;
00382 #else /* ACE_HAS_IPV6 */
00383 
00384   // IPv6 not supported... insure the family is set to IPv4
00385   address_family = AF_INET;
00386   this->set_type (address_family);
00387   this->inet_addr_.in4_.sin_family = static_cast<short> (address_family);
00388 #ifdef ACE_HAS_SOCKADDR_IN_SIN_LEN
00389   this->inet_addr_.in4_.sin_len = sizeof (this->inet_addr_.in4_);
00390 #endif
00391   struct in_addr addrv4;
00392   if (ACE_OS::inet_aton (host_name,
00393                          &addrv4) == 1)
00394     return this->set (port_number,
00395                       encode ? ACE_NTOHL (addrv4.s_addr) : addrv4.s_addr,
00396                       encode);
00397   else
00398     {
00399 #  if defined (ACE_VXWORKS) && defined (ACE_LACKS_GETHOSTBYNAME)
00400       hostent *hp = ACE_OS::gethostbyname (host_name);
00401 #  else
00402       hostent hentry;
00403       ACE_HOSTENT_DATA buf;
00404       int h_error = 0;  // Not the same as errno!
00405 
00406       hostent *hp = ACE_OS::gethostbyname_r (host_name, &hentry,
00407                                              buf, &h_error);
00408       if (hp == 0)
00409         errno = h_error;
00410 #  endif /* ACE_VXWORKS */
00411 
00412       if (hp == 0)
00413         {
00414           return -1;
00415         }
00416       else
00417         {
00418           (void) ACE_OS::memcpy ((void *) &addrv4.s_addr,
00419                                  hp->h_addr,
00420                                  hp->h_length);
00421           return this->set (port_number,
00422                             encode ? ACE_NTOHL (addrv4.s_addr) : addrv4.s_addr,
00423                             encode);
00424         }
00425     }
00426 #endif /* ACE_HAS_IPV6 */
00427 }
00428 
00429 // Helper function to get a port number from a port name.
00430 
00431 static int get_port_number_from_name (const char port_name[],
00432                                       const char protocol[])
00433 {
00434   // Maybe port_name is directly a port number?
00435   char *endp = 0;
00436   long port_number = ACE_OS::strtol (port_name, &endp, 10);
00437 
00438   if (*endp == '\0')
00439     {
00440       // port_name was really a number, and nothing else.
00441 
00442       // Check for overflow.
00443       if (port_number < 0 || port_number > ACE_MAX_DEFAULT_PORT)
00444         return -1;
00445 
00446       // Return the port number.  NOTE: this number must
00447       // be returned in network byte order!
00448       u_short n = static_cast<u_short> (port_number);
00449       n = ACE_HTONS (n);
00450       return n;
00451     }
00452 
00453   // We try to resolve port number from its name.
00454 
00455 #if defined (ACE_LACKS_GETSERVBYNAME)
00456   port_number = 0;
00457   ACE_UNUSED_ARG (port_name);
00458   ACE_UNUSED_ARG (protocol);
00459 #else
00460   port_number = -1;
00461   servent sentry;
00462   ACE_SERVENT_DATA buf;
00463   servent *sp = ACE_OS::getservbyname_r (port_name,
00464                                          protocol,
00465                                          &sentry,
00466                                          buf);
00467   if (sp != 0)
00468     port_number = sp->s_port;
00469 #endif /* ACE_LACKS_GETSERVBYNAME */
00470 
00471   return port_number;
00472 }
00473 
00474 // Initializes a ACE_INET_Addr from a <port_name> and the remote
00475 // <host_name>.
00476 
00477 int
00478 ACE_INET_Addr::set (const char port_name[],
00479                     const char host_name[],
00480                     const char protocol[])
00481 {
00482   ACE_TRACE ("ACE_INET_Addr::set");
00483 
00484   int const port_number = get_port_number_from_name (port_name, protocol);
00485   if (port_number == -1)
00486     {
00487       ACE_NOTSUP_RETURN (-1);
00488     }
00489 
00490   int address_family = PF_UNSPEC;
00491 #  if defined (ACE_HAS_IPV6)
00492   if (ACE_OS::strcmp (ACE_TEXT_CHAR_TO_TCHAR(protocol), ACE_TEXT ("tcp6")) == 0)
00493     address_family = AF_INET6;
00494 #  endif /* ACE_HAS_IPV6 */
00495 
00496   return this->set (static_cast<u_short> (port_number),
00497                     host_name, 0, address_family);
00498 }
00499 
00500 // Initializes a ACE_INET_Addr from a <port_name> and a 32 bit
00501 // Internet address.
00502 
00503 int
00504 ACE_INET_Addr::set (const char port_name[],
00505                     ACE_UINT32 inet_address,
00506                     const char protocol[])
00507 {
00508   ACE_TRACE ("ACE_INET_Addr::set");
00509 
00510   int const port_number = get_port_number_from_name (port_name, protocol);
00511   if (port_number == -1)
00512     {
00513       ACE_NOTSUP_RETURN (-1);
00514     }
00515 
00516   return this->set (static_cast<u_short> (port_number),
00517                     inet_address, 0);
00518 }
00519 
00520 // Creates a ACE_INET_Addr from a PORT_NUMBER and the remote
00521 // HOST_NAME.
00522 
00523 ACE_INET_Addr::ACE_INET_Addr (u_short port_number,
00524                               const char host_name[],
00525                               int address_family)
00526   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00527 {
00528   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00529   ACE_OS::memset (&this->inet_addr_, 0, sizeof (this->inet_addr_));
00530   if (this->set (port_number,
00531                  host_name,
00532                  1,
00533                  address_family) == -1)
00534     ACE_ERROR ((LM_ERROR,
00535                 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr: %p\n"),
00536                 ACE_TEXT_CHAR_TO_TCHAR ((host_name == 0) ?
00537                                         "<unknown>" : host_name)));
00538 }
00539 
00540 #if defined (ACE_HAS_WCHAR)
00541 ACE_INET_Addr::ACE_INET_Addr (u_short port_number,
00542                               const wchar_t host_name[],
00543                               int address_family)
00544   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00545 {
00546   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00547   ACE_OS::memset (&this->inet_addr_, 0, sizeof (this->inet_addr_));
00548   if (this->set (port_number,
00549                  host_name,
00550                  1,
00551                  address_family) == -1)
00552     ACE_ERROR ((LM_ERROR,
00553                 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr: %p\n"),
00554                 ACE_TEXT_WCHAR_TO_TCHAR ((host_name == 0) ?
00555                                          ACE_TEXT_WIDE ("<unknown>") :
00556                                          host_name)));
00557 }
00558 #endif /* ACE_HAS_WCHAR */
00559 
00560 // Creates a ACE_INET_Addr from a sockaddr_in structure.
00561 
00562 int
00563 ACE_INET_Addr::set (const sockaddr_in *addr, int len)
00564 {
00565   ACE_TRACE ("ACE_INET_Addr::set");
00566 
00567   if (addr->sin_family == AF_INET)
00568     {
00569       int maxlen = static_cast<int> (sizeof (this->inet_addr_.in4_));
00570       if (len > maxlen)
00571         len = maxlen;
00572       ACE_OS::memcpy (&this->inet_addr_.in4_, addr, len);
00573       this->base_set (AF_INET, len);
00574       return 0;
00575     }
00576 #if defined (ACE_HAS_IPV6)
00577   else if (addr->sin_family == AF_INET6)
00578     {
00579       int maxlen = static_cast<int> (sizeof (this->inet_addr_.in6_));
00580       if (len > maxlen)
00581         len = maxlen;
00582       ACE_OS::memcpy (&this->inet_addr_.in6_, addr, len);
00583       this->base_set (AF_INET6, len);
00584       return 0;
00585     }
00586 #endif /* ACE_HAS_IPV6 */
00587 
00588   errno = EAFNOSUPPORT;
00589   return -1;
00590 }
00591 
00592 // Return the address.
00593 
00594 void *
00595 ACE_INET_Addr::get_addr (void) const
00596 {
00597   ACE_TRACE ("ACE_INET_Addr::get_addr");
00598   return (void*)&this->inet_addr_;
00599 }
00600 
00601 void
00602 ACE_INET_Addr::set_addr (void *addr, int len)
00603 {
00604   this->set_addr (addr, len, 0);
00605 }
00606 
00607 // Set a pointer to the address.
00608 void
00609 ACE_INET_Addr::set_addr (void *addr, int /* len */, int map)
00610 {
00611   ACE_TRACE ("ACE_INET_Addr::set_addr");
00612   struct sockaddr_in *getfamily = static_cast<struct sockaddr_in *> (addr);
00613 
00614   if (getfamily->sin_family == AF_INET)
00615     {
00616 #if defined (ACE_HAS_IPV6)
00617       if (map)
00618         this->set_type (AF_INET6);
00619       else
00620 #endif /* ACE_HAS_IPV6 */
00621         this->set_type (AF_INET);
00622       this->set_port_number (getfamily->sin_port, 0);
00623       this->set_address (reinterpret_cast<const char*> (&getfamily->sin_addr),
00624                          sizeof (getfamily->sin_addr),
00625                          0, map);
00626     }
00627 #if defined (ACE_HAS_IPV6)
00628   else if (getfamily->sin_family == AF_INET6)
00629     {
00630       struct sockaddr_in6 *in6 = static_cast<struct sockaddr_in6*> (addr);
00631       this->set_port_number (in6->sin6_port, 0);
00632       this->set_address (reinterpret_cast<const char*> (&in6->sin6_addr),
00633                          sizeof (in6->sin6_addr),
00634                          0);
00635       this->inet_addr_.in6_.sin6_scope_id = in6->sin6_scope_id;
00636     }
00637 #endif // ACE_HAS_IPV6
00638 }
00639 
00640 // Creates a ACE_INET_Addr from a sockaddr_in structure.
00641 
00642 ACE_INET_Addr::ACE_INET_Addr (const sockaddr_in *addr, int len)
00643   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00644 {
00645   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00646   this->reset ();
00647   this->set (addr, len);
00648 }
00649 
00650 // Creates a ACE_INET_Addr from a PORT_NUMBER and an Internet address.
00651 
00652 ACE_INET_Addr::ACE_INET_Addr (u_short port_number,
00653                               ACE_UINT32 inet_address)
00654   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00655 {
00656   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00657   this->reset ();
00658   if (this->set (port_number, inet_address) == -1)
00659     ACE_ERROR ((LM_ERROR,
00660                 ACE_TEXT ("%p\n"),
00661                 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr")));
00662 }
00663 
00664 // Creates a ACE_INET_Addr from a PORT_NAME and the remote
00665 // HOST_NAME.
00666 
00667 ACE_INET_Addr::ACE_INET_Addr (const char port_name[],
00668                               const char host_name[],
00669                               const char protocol[])
00670   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00671 {
00672   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00673   this->reset ();
00674   if (this->set (port_name,
00675                  host_name,
00676                  protocol) == -1)
00677     ACE_ERROR ((LM_ERROR,
00678                 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr")));
00679 }
00680 
00681 #if defined (ACE_HAS_WCHAR)
00682 ACE_INET_Addr::ACE_INET_Addr (const wchar_t port_name[],
00683                               const wchar_t host_name[],
00684                               const wchar_t protocol[])
00685   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00686 {
00687   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00688   this->reset ();
00689   if (this->set (port_name,
00690                  host_name,
00691                  protocol) == -1)
00692     ACE_ERROR ((LM_ERROR,
00693                 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr")));
00694 }
00695 #endif /* ACE_HAS_WCHAR */
00696 
00697 // Creates a ACE_INET_Addr from a PORT_NAME and an Internet address.
00698 
00699 ACE_INET_Addr::ACE_INET_Addr (const char port_name[],
00700                               ACE_UINT32 inet_address,
00701                               const char protocol[])
00702   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00703 {
00704   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00705 #if !defined (ACE_LACKS_HTONL)
00706   this->reset ();
00707   if (this->set (port_name,
00708                  htonl (inet_address),
00709                  protocol) == -1)
00710     ACE_ERROR ((LM_ERROR,
00711                 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr")));
00712 #else
00713   ACE_UNUSED_ARG (port_name);
00714   ACE_UNUSED_ARG (inet_address);
00715   ACE_UNUSED_ARG (protocol);
00716 #endif
00717 }
00718 
00719 #if defined (ACE_HAS_WCHAR)
00720 ACE_INET_Addr::ACE_INET_Addr (const wchar_t port_name[],
00721                               ACE_UINT32 inet_address,
00722                               const wchar_t protocol[])
00723   : ACE_Addr (determine_type (), sizeof (inet_addr_))
00724 {
00725   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00726 #if !defined (ACE_LACKS_HTONL)
00727   this->reset ();
00728   if (this->set (port_name,
00729                  htonl (inet_address),
00730                  protocol) == -1)
00731     ACE_ERROR ((LM_ERROR,
00732                 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr")));
00733 #else
00734   ACE_UNUSED_ARG (port_name);
00735   ACE_UNUSED_ARG (inet_address);
00736   ACE_UNUSED_ARG (protocol);
00737 #endif
00738 }
00739 #endif /* ACE_HAS_WCHAR */
00740 
00741 ACE_INET_Addr::~ACE_INET_Addr (void)
00742 {
00743 }
00744 
00745 int
00746 ACE_INET_Addr::get_host_name (char hostname[],
00747                               size_t len) const
00748 {
00749   ACE_TRACE ("ACE_INET_Addr::get_host_name");
00750 
00751   int result;
00752   if (len > 1)
00753     {
00754       result = this->get_host_name_i (hostname,len);
00755       if (result < 0)
00756         {
00757           if (result == -2)
00758             // We know that hostname is nul-terminated
00759             result = -1;
00760           else
00761             {
00762               //result == -1;
00763               // This could be worse than hostname[len -1] = '\0'?
00764               hostname[0] = '\0';
00765             }
00766         }
00767     }
00768   else
00769     {
00770       if (len == 1)
00771         hostname[0] = '\0';
00772       result = -1;
00773     }
00774 
00775   return result;
00776 }
00777 
00778 #if defined (ACE_HAS_WCHAR)
00779 int
00780 ACE_INET_Addr::get_host_name (wchar_t hostname[],
00781                               size_t len) const
00782 {
00783   ACE_TRACE ("ACE_INET_Addr::get_host_name");
00784 
00785   char char_hostname [MAXHOSTNAMELEN + 1];
00786 
00787   // We have a build in limitation of MAXHOSTNAMELEN
00788   if (len > MAXHOSTNAMELEN + 1)
00789     len = MAXHOSTNAMELEN + 1;
00790 
00791   // Call the char version
00792   int result = this->get_host_name (char_hostname, len);
00793 
00794   // And copy it over, if successful
00795   if (result == 0)
00796     ACE_OS::strcpy (hostname,
00797                     ACE_Ascii_To_Wide (char_hostname).wchar_rep ());
00798 
00799   return result;
00800 }
00801 #endif /* ACE_HAS_WCHAR */
00802 
00803 // Return the character representation of the hostname.
00804 
00805 const char *
00806 ACE_INET_Addr::get_host_name (void) const
00807 {
00808   ACE_TRACE ("ACE_INET_Addr::get_host_name");
00809 
00810   static char name[MAXHOSTNAMELEN + 1];
00811   if (this->get_host_name (name, MAXHOSTNAMELEN + 1) == -1)
00812     ACE_OS::strcpy (name, "<unknown>");
00813   return name;
00814 }
00815 
00816 void
00817 ACE_INET_Addr::set_port_number (u_short port_number,
00818                                 int encode)
00819 {
00820   ACE_TRACE ("ACE_INET_Addr::set_port_number");
00821 
00822   if (encode)
00823     port_number = ACE_HTONS (port_number);
00824 
00825 #if defined (ACE_HAS_IPV6)
00826   if (this->get_type () == AF_INET6)
00827     this->inet_addr_.in6_.sin6_port = port_number;
00828   else
00829 #endif /* ACE_HAS_IPV6 */
00830   this->inet_addr_.in4_.sin_port = port_number;
00831 }
00832 
00833 // returns -2 when the hostname is truncated
00834 int
00835 ACE_INET_Addr::get_host_name_i (char hostname[], size_t len) const
00836 {
00837   ACE_TRACE ("ACE_INET_Addr::get_host_name_i");
00838 
00839 #if defined (ACE_HAS_IPV6)
00840   if ((this->get_type () == PF_INET6 &&
00841        0 == ACE_OS::memcmp (&this->inet_addr_.in6_.sin6_addr,
00842                             &in6addr_any,
00843                             sizeof (this->inet_addr_.in6_.sin6_addr)))
00844       ||
00845       (this->get_type () == PF_INET &&
00846        this->inet_addr_.in4_.sin_addr.s_addr == INADDR_ANY))
00847 #else
00848   if (this->inet_addr_.in4_.sin_addr.s_addr == INADDR_ANY)
00849 #endif /* ACE_HAS_IPV6 */
00850     {
00851       if (ACE_OS::hostname (hostname, len) == -1)
00852         return -1;
00853       else
00854         return 0;
00855     }
00856   else
00857     {
00858 #if defined (ACE_VXWORKS) && defined (ACE_LACKS_GETHOSTBYADDR)
00859       ACE_UNUSED_ARG (len);
00860       int error =
00861         ::hostGetByAddr ((int) this->inet_addr_.in4_.sin_addr.s_addr,
00862                          hostname);
00863       if (error == OK)
00864         return 0;
00865       else
00866         {
00867           errno = error;
00868           return -1;
00869         }
00870 #else
00871       void* addr = this->ip_addr_pointer ();
00872       int   size = this->ip_addr_size ();
00873       int   type = this->get_type ();
00874 
00875 #  if defined (ACE_HAS_IPV6) && defined (ACE_HAS_BROKEN_GETHOSTBYADDR_V4MAPPED)
00876       // Most OS can not handle IPv6-mapped-IPv4 addresses (even
00877       // though they are meant to) so map them back to IPv4 addresses
00878       // before trying to resolve them
00879       in_addr demapped_addr;
00880       if (type == PF_INET6 &&
00881           (this->is_ipv4_mapped_ipv6 () || this->is_ipv4_compat_ipv6 ()))
00882         {
00883           ACE_OS::memcpy (&demapped_addr.s_addr, &this->inet_addr_.in6_.sin6_addr.s6_addr[12], 4);
00884           addr = &demapped_addr;
00885           size = sizeof(demapped_addr);
00886           type = PF_INET;
00887         }
00888 #  endif /* ACE_HAS_IPV6 */
00889 
00890 #  if defined (DIGITAL_UNIX) && defined (__GNUC__)
00891       hostent * const hp =
00892         ACE_OS::gethostbyaddr (static_cast <char *> (addr), size, type);
00893 #  else
00894       int h_error;  // Not the same as errno!
00895       hostent hentry;
00896       ACE_HOSTENT_DATA buf;
00897       hostent * const hp =
00898         ACE_OS::gethostbyaddr_r (static_cast <char *> (addr),
00899                                  size,
00900                                  type,
00901                                  &hentry,
00902                                  buf,
00903                                  &h_error);
00904 #  endif /* DIGITAL_UNIX */
00905 
00906       if (hp == 0 || hp->h_name == 0)
00907         return -1;
00908 
00909       if (ACE_OS::strlen (hp->h_name) >= len)
00910         {
00911           // We know the length, so use memcpy
00912           if (len > 0)
00913             {
00914               ACE_OS::memcpy (hostname, hp->h_name, len - 1);
00915               hostname[len-1]= '\0';
00916             }
00917           errno = ENOSPC;
00918           return -2;  // -2 Means that we have a good string
00919           // Using errno looks ok, but ENOSPC could be set on
00920           // other places.
00921         }
00922 
00923       ACE_OS::strcpy (hostname, hp->h_name);
00924       return 0;
00925 #endif /* ACE_VXWORKS */
00926     }
00927 }
00928 
00929 int ACE_INET_Addr::set_address (const char *ip_addr,
00930                                 int len,
00931                                 int encode /* = 1 */,
00932                                 int map /* = 0 */)
00933 {
00934   ACE_TRACE ("ACE_INET_Addr::set_address");
00935   // This is really intended for IPv4. If the object is IPv4, or the type
00936   // hasn't been set but it's a 4-byte address, go ahead. If this is an
00937   // IPv6 object and <encode> is requested, refuse.
00938   if (encode && len != 4)
00939     {
00940       errno = EAFNOSUPPORT;
00941       return -1;
00942     }
00943 
00944   if (len == 4)
00945     {
00946       ACE_UINT32 ip4 = *reinterpret_cast<const ACE_UINT32 *> (ip_addr);
00947       if (encode)
00948         ip4 = ACE_HTONL (ip4);
00949 
00950 
00951       if (this->get_type () == AF_INET && map == 0) {
00952         this->base_set (AF_INET, sizeof (this->inet_addr_.in4_));
00953 #ifdef ACE_HAS_SOCKADDR_IN_SIN_LEN
00954         this->inet_addr_.in4_.sin_len = sizeof (this->inet_addr_.in4_);
00955 #endif
00956         this->inet_addr_.in4_.sin_family = AF_INET;
00957         this->set_size (sizeof (this->inet_addr_.in4_));
00958         ACE_OS::memcpy (&this->inet_addr_.in4_.sin_addr,
00959                         &ip4,
00960                         len);
00961       }
00962 #if defined (ACE_HAS_IPV6)
00963       else if (map == 0)
00964         {
00965           // this->set_type (AF_INET);
00966           this->base_set (AF_INET, sizeof (this->inet_addr_.in4_));
00967 #ifdef ACE_HAS_SOCKADDR_IN_SIN_LEN
00968           this->inet_addr_.in4_.sin_len = sizeof (this->inet_addr_.in4_);
00969 #endif
00970           this->inet_addr_.in4_.sin_family = AF_INET;
00971           this->set_size (sizeof (this->inet_addr_.in4_));
00972           ACE_OS::memcpy (&this->inet_addr_.in4_.sin_addr,
00973                           &ip4, len);
00974         }
00975       // If given an IPv4 address to copy to an IPv6 object, map it to
00976       // an IPv4-mapped IPv6 address.
00977       else
00978         {
00979           this->base_set (AF_INET6, sizeof (this->inet_addr_.in6_));
00980 #ifdef ACE_HAS_SOCKADDR_IN6_SIN6_LEN
00981           this->inet_addr_.in6_.sin6_len = sizeof (this->inet_addr_.in6_);
00982 #endif
00983           this->inet_addr_.in6_.sin6_family = AF_INET6;
00984           this->set_size (sizeof (this->inet_addr_.in6_));
00985           if (ip4 == ACE_HTONL (INADDR_ANY))
00986             {
00987               in6_addr const ip6 = in6addr_any;
00988               ACE_OS::memcpy (&this->inet_addr_.in6_.sin6_addr,
00989                               &ip6,
00990                               sizeof (ip6));
00991               return 0;
00992             }
00993 
00994           // Build up a 128 bit address.  An IPv4-mapped IPv6 address
00995           // is defined as 0:0:0:0:0:ffff:IPv4_address.  This is defined
00996           // in RFC 1884 */
00997           ACE_OS::memset (&this->inet_addr_.in6_.sin6_addr, 0, 16);
00998           this->inet_addr_.in6_.sin6_addr.s6_addr[10] =
00999             this->inet_addr_.in6_.sin6_addr.s6_addr[11] = 0xff;
01000           ACE_OS::memcpy
01001             (&this->inet_addr_.in6_.sin6_addr.s6_addr[12], &ip4, 4);
01002         }
01003 #endif /* ACE_HAS_IPV6 */
01004       return 0;
01005     }   /* end if (len == 4) */
01006 #if defined (ACE_HAS_IPV6)
01007   else if (len == 16)
01008     {
01009       if (this->get_type () != PF_INET6)
01010         {
01011           errno = EAFNOSUPPORT;
01012           return -1;
01013         }
01014       // We protect ourselves up above so IPv6 must be possible here.
01015       this->base_set (AF_INET6, sizeof (this->inet_addr_.in6_));
01016       this->inet_addr_.in6_.sin6_family = AF_INET6;
01017 #ifdef ACE_HAS_SOCKADDR_IN6_SIN6_LEN
01018       this->inet_addr_.in6_.sin6_len = sizeof (this->inet_addr_.in6_);
01019 #endif
01020       ACE_OS::memcpy (&this->inet_addr_.in6_.sin6_addr, ip_addr, len);
01021 
01022       return 0;
01023     } /* end len == 16 */
01024 #endif /* ACE_HAS_IPV6 */
01025 
01026   // Here with an unrecognized length.
01027   errno = EAFNOSUPPORT;
01028   return -1;
01029 
01030 }
01031 
01032 #if (defined (__linux__) || defined (ACE_WIN32)) && defined (ACE_HAS_IPV6)
01033 int
01034 ACE_INET_Addr::set_interface (const char *intf_name)
01035 {
01036   if (this->get_type () == PF_INET6 &&
01037       (IN6_IS_ADDR_LINKLOCAL (&this->inet_addr_.in6_.sin6_addr) ||
01038        IN6_IS_ADDR_MC_LINKLOCAL (&this->inet_addr_.in6_.sin6_addr)))
01039     {
01040 #if defined (__linux__)
01041       this->inet_addr_.in6_.sin6_scope_id =
01042         ACE_OS::if_nametoindex (intf_name);
01043 #else
01044       this->inet_addr_.in6_.sin6_scope_id =
01045         intf_name ? ACE_OS::atoi (intf_name) : 0;
01046 #endif
01047       // check to see if the interface lookup succeeded
01048       if (this->inet_addr_.in6_.sin6_scope_id != 0)
01049         return 0;
01050       else
01051         return -1;
01052     }
01053   else
01054     return 0;
01055 
01056 }
01057 #endif /* __linux && ACE_HAS_IPV6 */
01058 
01059 const char *
01060 ACE_INET_Addr::get_host_addr (char *dst, int size) const
01061 {
01062 #if defined (ACE_HAS_IPV6)
01063   if (this->get_type () == AF_INET6)
01064     {
01065       // mcorino@remedy.nl - Aug-26, 2005
01066       // I don't think this should be done because it results in a decimal address
01067       // representation which is not distinguishable from the IPv4 form which makes
01068       // it impossible to resolve back to an IPv6 INET_Addr without prior knowledge
01069       // that this was such an address to begin with.
01070 
01071       //if (IN6_IS_ADDR_V4MAPPED (&this->inet_addr_.in6_.sin6_addr))
01072       //{
01073       //  ACE_UINT32 addr;
01074       //  addr = this->get_ip_address();
01075       //  addr = ACE_HTONL (addr);
01076       //  return ACE_OS::inet_ntop (AF_INET, &addr, dst, size);
01077       //}
01078 
01079 #  if defined (ACE_WIN32)
01080       if (0 == ::getnameinfo (reinterpret_cast<const sockaddr*> (&this->inet_addr_.in6_),
01081                               this->get_size (),
01082                               dst,
01083                               size,
01084                               0, 0,    // Don't want service name
01085                               NI_NUMERICHOST))
01086         return dst;
01087       ACE_OS::set_errno_to_wsa_last_error ();
01088       return 0;
01089 #  else
01090       const char *ch = ACE_OS::inet_ntop (AF_INET6,
01091                                           &this->inet_addr_.in6_.sin6_addr,
01092                                           dst,
01093                                           size);
01094 #if defined (__linux__)
01095       if ((IN6_IS_ADDR_LINKLOCAL (&this->inet_addr_.in6_.sin6_addr) ||
01096            IN6_IS_ADDR_MC_LINKLOCAL (&this->inet_addr_.in6_.sin6_addr)) &&
01097           this->inet_addr_.in6_.sin6_scope_id != 0)
01098         {
01099           char scope_buf[32];
01100           ACE_OS::sprintf (scope_buf, "%%%u", this->inet_addr_.in6_.sin6_scope_id);
01101           if ((ACE_OS::strlen (ch)+ACE_OS::strlen (scope_buf)) < (size_t)size)
01102             {
01103               ACE_OS::strcat (dst, scope_buf);
01104             }
01105         }
01106 #endif
01107       return ch;
01108 #  endif /* ACE_WIN32 */
01109     }
01110 #endif /* ACE_HAS_IPV6 */
01111 
01112 #if defined (ACE_VXWORKS)
01113   ACE_UNUSED_ARG (dst);
01114   ACE_UNUSED_ARG (size);
01115 
01116   // It would be nice to be able to encapsulate this into
01117   // ACE_OS::inet_ntoa(), but that would lead to either inefficiencies
01118   // on vxworks or lack of thread safety.
01119   //
01120   // So, we use the way that vxworks suggests.
01121   ACE_INET_Addr *ncthis = const_cast<ACE_INET_Addr *> (this);
01122   inet_ntoa_b(this->inet_addr_.in4_.sin_addr, ncthis->buf_);
01123   ACE_OS::strsncpy (dst, &buf_[0], size);
01124   return &buf_[0];
01125 #else /* ACE_VXWORKS */
01126   char *ch = ACE_OS::inet_ntoa (this->inet_addr_.in4_.sin_addr);
01127   ACE_OS::strsncpy (dst, ch, size);
01128   return ch;
01129 #endif
01130 }
01131 
01132 // Return the dotted Internet address.
01133 const char *
01134 ACE_INET_Addr::get_host_addr (void) const
01135 {
01136   ACE_TRACE ("ACE_INET_Addr::get_host_addr");
01137 #if defined (ACE_HAS_IPV6)
01138   static char buf[INET6_ADDRSTRLEN];
01139   return this->get_host_addr (buf, INET6_ADDRSTRLEN);
01140 #else /* ACE_HAS_IPV6 */
01141 #  if defined (ACE_VXWORKS)
01142   // It would be nice to be able to encapsulate this into
01143   // ACE_OS::inet_ntoa(), but that would lead to either inefficiencies
01144   // on vxworks or lack of thread safety.
01145   //
01146   // So, we use the way that vxworks suggests.
01147   ACE_INET_Addr *ncthis = const_cast<ACE_INET_Addr *> (this);
01148   inet_ntoa_b (this->inet_addr_.in4_.sin_addr, ncthis->buf_);
01149   return &buf_[0];
01150 #  else /* ACE_VXWORKS */
01151   return ACE_OS::inet_ntoa (this->inet_addr_.in4_.sin_addr);
01152 #  endif /* !ACE_VXWORKS */
01153 #endif /* !ACE_HAS_IPV6 */
01154 }
01155 
01156 // Return the 4-byte IP address, converting it into host byte order.
01157 ACE_UINT32
01158 ACE_INET_Addr::get_ip_address (void) const
01159 {
01160   ACE_TRACE ("ACE_INET_Addr::get_ip_address");
01161 #if defined (ACE_HAS_IPV6)
01162   if (this->get_type () == AF_INET6)
01163     {
01164       if (IN6_IS_ADDR_V4MAPPED (&this->inet_addr_.in6_.sin6_addr) ||
01165           IN6_IS_ADDR_V4COMPAT (&this->inet_addr_.in6_.sin6_addr)    )
01166         {
01167           ACE_UINT32 addr;
01168           // Return the last 32 bits of the address
01169           char *thisaddrptr = (char*)this->ip_addr_pointer ();
01170           thisaddrptr += 128/8 - 32/8;
01171           ACE_OS::memcpy (&addr, thisaddrptr, sizeof (addr));
01172           return ACE_NTOHL (addr);
01173         }
01174 
01175       ACE_ERROR ((LM_ERROR,
01176                   ACE_TEXT ("ACE_INET_Addr::get_ip_address: address is a IPv6 address not IPv4\n")));
01177       errno = EAFNOSUPPORT;
01178       return 0;
01179     }
01180 #endif /* ACE_HAS_IPV6 */
01181   return ACE_NTOHL (ACE_UINT32 (this->inet_addr_.in4_.sin_addr.s_addr));
01182 }
01183 
01184 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:18:39 2010 for ACE by  doxygen 1.4.7