Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

INET_Addr.cpp

Go to the documentation of this file.
00001 #include "ace_pch.h"
00002 // $Id: INET_Addr.cpp,v 1.1.1.4.2.1 2003/03/13 19:44:21 chad Exp $
00003 
00004 // Defines the Internet domain address family address format.
00005 
00006 #include "ace/INET_Addr.h"
00007 #include "ace/Log_Msg.h"
00008 
00009 #if !defined (__ACE_INLINE__)
00010 #include "ace/INET_Addr.i"
00011 #endif /* __ACE_INLINE__ */
00012 
00013 ACE_RCSID (ace,
00014            INET_Addr,
00015            "$Id: INET_Addr.cpp,v 1.1.1.4.2.1 2003/03/13 19:44:21 chad Exp $")
00016 
00017 ACE_ALLOC_HOOK_DEFINE(ACE_INET_Addr)
00018 
00019 // Transform the current address into string format.
00020 
00021 int
00022 ACE_INET_Addr::addr_to_string (ACE_TCHAR s[],
00023                                size_t size,
00024                                int ipaddr_format) const
00025 {
00026   ACE_TRACE ("ACE_INET_Addr::addr_to_string");
00027 
00028   // XXX Can we (should we) include the scope id for IPv6 addresses?
00029 
00030   size_t total_len = (ipaddr_format == 0 ?
00031                       ACE_OS::strlen (this->get_host_name ()) :
00032                       ACE_OS::strlen (this->get_host_addr ()))
00033     + ACE_OS::strlen ("65536") // Assume the max port number.
00034     + sizeof (':')
00035 #if defined ACE_HAS_IPV6
00036     + ACE_OS::strlen ("[]")
00037 #endif
00038     + sizeof ('\0'); // For trailing '\0'.
00039 
00040   if (size < total_len)
00041     return -1;
00042   else
00043     {
00044       ACE_OS::sprintf (s,
00045 #if defined ACE_HAS_IPV6
00046                        ACE_LIB_TEXT ("[%s]:%d"),
00047 #else
00048                        ACE_LIB_TEXT ("%s:%d"),
00049 #endif
00050                        ACE_TEXT_CHAR_TO_TCHAR (ipaddr_format == 0
00051                                                ? this->get_host_name ()
00052                                                : this->get_host_addr ()),
00053                        this->get_port_number ());
00054       return 0;
00055     }
00056 }
00057 
00058 void
00059 ACE_INET_Addr::dump (void) const
00060 {
00061   ACE_TRACE ("ACE_INET_Addr::dump");
00062 
00063   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00064 
00065   ACE_TCHAR s[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16];
00066   this->addr_to_string(s, ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16);
00067   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("%s"), s));
00068   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00069 }
00070 
00071 // Compare two addresses for inequality.
00072 
00073 int
00074 ACE_INET_Addr::operator != (const ACE_INET_Addr &sap) const
00075 {
00076   ACE_TRACE ("ACE_INET_Addr::operator !=");
00077   return !((*this) == sap);
00078 }
00079 
00080 // Compare two addresses for equality.
00081 
00082 int
00083 ACE_INET_Addr::operator == (const ACE_INET_Addr &sap) const
00084 {
00085   ACE_TRACE ("ACE_INET_Addr::operator ==");
00086 
00087   if (this->get_type () != sap.get_type () ||
00088       this->get_size () != sap.get_size ()    )
00089     return 0;
00090 
00091   return (ACE_OS::memcmp (&this->inet_addr_,
00092                           &sap.inet_addr_,
00093                           this->get_size ()) == 0);
00094 }
00095 
00096 ACE_INET_Addr::ACE_INET_Addr (void)
00097   : ACE_Addr (this->determine_type(), sizeof (inet_addr_))
00098 {
00099   // ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00100   this->reset();
00101 }
00102 
00103 int
00104 ACE_INET_Addr::set (const ACE_INET_Addr &sa)
00105 {
00106   ACE_TRACE ("ACE_INET_Addr::set");
00107 
00108   if (sa.get_type () == AF_ANY)
00109     // Ugh, this is really a base class, so don't copy it.
00110     ACE_OS::memset (&this->inet_addr_, 0, sizeof (this->inet_addr_));
00111   else
00112     // It's ok to make the copy.
00113     ACE_OS::memcpy (&this->inet_addr_, &sa.inet_addr_, sa.get_size ());
00114 
00115   return 0;
00116 }
00117 
00118 // Transform the string into the current addressing format.
00119 
00120 int
00121 ACE_INET_Addr::string_to_addr (const char s[])
00122 {
00123   ACE_TRACE ("ACE_INET_Addr::string_to_addr");
00124   int result;
00125   char *ip_addr;
00126 
00127   // Need to make a duplicate since we'll be overwriting the string.
00128   ACE_ALLOCATOR_RETURN (ip_addr,
00129                         ACE_OS::strdup (s),
00130                         -1);
00131   // We use strrchr because of IPv6 addresses.
00132   char *port_p = ACE_OS::strrchr (ip_addr, ':');
00133 
00134   if (port_p == 0) // Assume it's a port number.
00135     {
00136       if (ACE_OS::strspn (ip_addr, "1234567890") == ACE_OS::strlen (ip_addr))
00137         { // port number
00138           u_short port = (u_short) ACE_OS::atoi (ip_addr);
00139           result = this->set (port, ACE_UINT32 (INADDR_ANY));
00140         }
00141       else // port name
00142         result = this->set (ip_addr, ACE_UINT32 (INADDR_ANY));
00143     }
00144   else
00145     {
00146       *port_p = '\0'; ++port_p; // skip over ':'
00147 
00148       if (ACE_OS::strspn (port_p, "1234567890") == ACE_OS::strlen (port_p))
00149         {
00150           u_short port = (u_short) ACE_OS::atoi (port_p);
00151           result = this->set (port, ip_addr);
00152         }
00153       else
00154         result = this->set (port_p, ip_addr);
00155     }
00156 
00157   ACE_OS::free (ACE_MALLOC_T (ip_addr));
00158   return result;
00159 }
00160 
00161 int
00162 ACE_INET_Addr::set (const char address[])
00163 {
00164   ACE_TRACE ("ACE_INET_Addr::set");
00165   return this->string_to_addr (address);
00166 }
00167 
00168 ACE_INET_Addr::ACE_INET_Addr (const char address[])
00169   : ACE_Addr (this->determine_type(), sizeof (inet_addr_))
00170 {
00171   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00172   this->reset();
00173   this->set (address);
00174 }
00175 
00176 #if defined (ACE_HAS_WCHAR)
00177 ACE_INET_Addr::ACE_INET_Addr (const wchar_t address[])
00178   : ACE_Addr (this->determine_type(), sizeof (inet_addr_))
00179 {
00180   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00181   this->reset();
00182   this->set (address);
00183 }
00184 
00185 #endif /* ACE_HAS_WCHAR */
00186 
00187 // Copy constructor.
00188 
00189 ACE_INET_Addr::ACE_INET_Addr (const ACE_INET_Addr &sa)
00190   : ACE_Addr (sa.get_type (), sa.get_size())
00191 {
00192   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00193   this->reset();
00194   this->set (sa);
00195 }
00196 
00197 // Initializes a ACE_INET_Addr from a PORT_NUMBER and a 32 bit Internet
00198 // address.
00199 
00200 int
00201 ACE_INET_Addr::set (u_short port_number,
00202                     ACE_UINT32 inet_address,
00203                     int encode)
00204 {
00205   ACE_TRACE ("ACE_INET_Addr::set");
00206   this->set_address (ACE_reinterpret_cast (const char *, &inet_address),
00207                      sizeof inet_address,
00208                      encode);
00209   this->set_port_number (port_number, encode);
00210 
00211   return 0;
00212 }
00213 
00214 
00215 // Initializes a ACE_INET_Addr from a PORT_NUMBER and the remote
00216 // HOST_NAME.
00217 
00218 int
00219 ACE_INET_Addr::set (u_short port_number,
00220                     const char host_name[],
00221                     int encode,
00222                     int address_family)
00223 {
00224   ACE_TRACE ("ACE_INET_Addr::set");
00225 
00226   // Yow, someone gave us a NULL host_name!
00227   if (host_name == 0)
00228     {
00229       errno = EINVAL;
00230       return -1;
00231     }
00232 
00233   ACE_OS_String::memset ((void *) &this->inet_addr_,
00234                          0,
00235                          sizeof this->inet_addr_);
00236 
00237 #if defined (ACE_HAS_IPV6)
00238   struct addrinfo hints, *res, *res0;
00239   int error;
00240   ACE_OS_String::memset (&hints, 0, sizeof (hints));
00241 
00242   hints.ai_family = address_family;
00243 
00244   error = getaddrinfo (host_name, 0, &hints, &res0);
00245   if (error)
00246     return -1;
00247 
00248   int ret = -1;
00249   for (res = res0; res != 0; res = res->ai_next)
00250     {
00251       if (res->ai_family == AF_INET || res->ai_family == AF_INET6)
00252         {
00253           this->set_type (res->ai_family);
00254           this->set_addr (res->ai_addr, res->ai_addrlen);
00255           this->set_port_number (port_number, encode);
00256           ret = 0;
00257           break;
00258         }
00259     }
00260   freeaddrinfo (res0);
00261   return ret;
00262 
00263 #else /* ACE_HAS_IPV6 */
00264 
00265   // IPv6 not supported... insure the family is set to IPv4
00266   address_family = AF_INET;
00267   this->set_type (address_family);
00268   this->inet_addr_.in4_.sin_family = address_family;
00269   struct in_addr addrv4;
00270   if (ACE_OS::inet_aton (host_name,
00271                          &addrv4) == 1)
00272     return this->set (port_number,
00273                       encode ? ntohl (addrv4.s_addr) : addrv4.s_addr,
00274                       encode);
00275   else
00276     {
00277 #  if defined (VXWORKS) || defined (CHORUS)
00278       hostent *hp = ACE_OS::gethostbyname (host_name);
00279 #  else
00280       hostent hentry;
00281       ACE_HOSTENT_DATA buf;
00282       int h_error;  // Not the same as errno!
00283 
00284       hostent *hp = ACE_OS::gethostbyname_r (host_name, &hentry,
00285                                              buf, &h_error);
00286 #  endif /* VXWORKS */
00287 
00288       if (hp == 0)
00289         {
00290           return -1;
00291         }
00292       else
00293         {
00294           (void) ACE_OS_String::memcpy ((void *) &addrv4.s_addr,
00295                                         hp->h_addr,
00296                                         hp->h_length);
00297           return this->set (port_number,
00298                             encode ? ntohl (addrv4.s_addr) : addrv4.s_addr,
00299                             encode);
00300         }
00301     }
00302 #endif /* ACE_HAS_IPV6 */
00303 }
00304 
00305 
00306 // Initializes a ACE_INET_Addr from a <port_name> and the remote
00307 // <host_name>.
00308 
00309 int
00310 ACE_INET_Addr::set (const char port_name[],
00311                     const char host_name[],
00312                     const char protocol[])
00313 {
00314   ACE_TRACE ("ACE_INET_Addr::set");
00315 
00316 #if defined (VXWORKS) || defined (CHORUS) || defined (ACE_LACKS_GETSERVBYNAME)
00317   ACE_UNUSED_ARG (port_name);
00318   ACE_UNUSED_ARG (host_name);
00319   ACE_UNUSED_ARG (protocol);
00320   ACE_NOTSUP_RETURN (-1);
00321 #else
00322   servent sentry;
00323   ACE_SERVENT_DATA buf;
00324 
00325   servent *sp = ACE_OS::getservbyname_r (port_name,
00326                                          protocol,
00327                                          &sentry,
00328                                          buf);
00329   if (sp == 0)
00330     return -1;
00331 
00332   int address_family = PF_UNSPEC;
00333 #  if defined (ACE_HAS_IPV6)
00334   if (ACE_OS_String::strcmp (protocol, ACE_LIB_TEXT ("tcp6")) == 0)
00335     address_family = AF_INET6;
00336 #  endif /* ACE_HAS_IPV6 */
00337 
00338   return this->set (sp->s_port, host_name, 0, address_family);
00339 #endif /* VXWORKS */
00340 }
00341 
00342 // Initializes a ACE_INET_Addr from a <port_name> and a 32 bit Internet
00343 // address.
00344 
00345 int
00346 ACE_INET_Addr::set (const char port_name[],
00347                     ACE_UINT32 inet_address,
00348                     const char protocol[])
00349 {
00350   ACE_TRACE ("ACE_INET_Addr::set");
00351 
00352 #if defined (VXWORKS) || defined (CHORUS) || defined (ACE_LACKS_GETSERVBYNAME)
00353   ACE_UNUSED_ARG (port_name);
00354   ACE_UNUSED_ARG (inet_address);
00355   ACE_UNUSED_ARG (protocol);
00356   ACE_NOTSUP_RETURN (-1);
00357 #else
00358   servent sentry;
00359   ACE_SERVENT_DATA buf;
00360 
00361   servent *sp = ACE_OS::getservbyname_r (port_name,
00362                                          protocol,
00363                                          &sentry,
00364                                          buf);
00365   if (sp == 0)
00366     return -1;
00367   else
00368     return this->set (sp->s_port, inet_address, 0);
00369 #endif /* VXWORKS */
00370 }
00371 
00372 // Creates a ACE_INET_Addr from a PORT_NUMBER and the remote
00373 // HOST_NAME.
00374 
00375 
00376 ACE_INET_Addr::ACE_INET_Addr (u_short port_number,
00377                               const char host_name[],
00378                               int address_family)
00379   : ACE_Addr (this->determine_type(), sizeof (inet_addr_))
00380 {
00381   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00382   ACE_OS::memset (&this->inet_addr_, 0, sizeof (this->inet_addr_));
00383   if (this->set (port_number,
00384                  host_name,
00385                  1,
00386                  address_family) == -1)
00387 #if defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS)
00388     ACE_ERROR ((LM_ERROR,
00389                 (char *)"ACE_INET_Addr::ACE_INET_Addr: %p\n",
00390                 (((char *) host_name == 0) ?
00391                  ((char *) "<unknown>") :
00392                  ((char *) (host_name)))));
00393 #else /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
00394     ACE_ERROR ((LM_ERROR,
00395                 ACE_LIB_TEXT ("ACE_INET_Addr::ACE_INET_Addr: %p\n"),
00396                 ACE_TEXT_CHAR_TO_TCHAR ((host_name == 0) ?
00397                                         "<unknown>" : host_name)));
00398 #endif /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
00399 }
00400 
00401 #if defined (ACE_HAS_WCHAR)
00402 ACE_INET_Addr::ACE_INET_Addr (u_short port_number,
00403                               const wchar_t host_name[],
00404                               int address_family)
00405   : ACE_Addr (this->determine_type(), sizeof (inet_addr_))
00406 {
00407   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00408   ACE_OS::memset (&this->inet_addr_, 0, sizeof (this->inet_addr_));
00409   if (this->set (port_number,
00410                  host_name,
00411                  1,
00412                  address_family) == -1)
00413 #if defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS)
00414     ACE_ERROR ((LM_ERROR,
00415                 (char *)"ACE_INET_Addr::ACE_INET_Addr: %p\n",
00416                 (((char *) host_name == 0) ?
00417                  ((char *) "<unknown>") :
00418                  ((char *) (host_name)))));
00419 #else /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
00420     ACE_ERROR ((LM_ERROR,
00421                 ACE_LIB_TEXT ("ACE_INET_Addr::ACE_INET_Addr: %p\n"),
00422                 ACE_TEXT_WCHAR_TO_TCHAR ((host_name == 0) ?
00423                                          ACE_TEXT_WIDE ("<unknown>") :
00424                                          host_name)));
00425 #endif /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
00426 }
00427 #endif /* ACE_HAS_WCHAR */
00428 
00429 // Creates a ACE_INET_Addr from a sockaddr_in structure.
00430 
00431 int
00432 ACE_INET_Addr::set (const sockaddr_in *addr, int len)
00433 {
00434   ACE_TRACE ("ACE_INET_Addr::set");
00435 
00436   if (addr->sin_family == AF_INET)
00437     {
00438       ACE_OS::memcpy (&this->inet_addr_.in4_, addr, len);
00439       this->base_set (AF_INET, len);
00440       return 0;
00441     }
00442 #if defined (ACE_HAS_IPV6)
00443   else if (addr->sin_family == AF_INET6)
00444     {
00445       ACE_OS::memcpy (&this->inet_addr_.in6_, addr, len);
00446       this->base_set (AF_INET6, len);
00447       return 0;
00448     }
00449 #endif /* ACE_HAS_IPV6 */
00450 
00451   errno = EAFNOSUPPORT;
00452   return -1;
00453 }
00454 
00455 // Set a pointer to the address.
00456 void
00457 ACE_INET_Addr::set_addr (void *addr, int /* len */)
00458 {
00459   ACE_TRACE ("ACE_INET_Addr::set_addr");
00460   struct sockaddr_in *getfamily = ACE_static_cast (struct sockaddr_in *, addr);
00461 
00462   if (getfamily->sin_family == AF_INET)
00463     {
00464       this->set_port_number (getfamily->sin_port, 0);
00465       this->set_address (ACE_reinterpret_cast (const char*, &getfamily->sin_addr),
00466                          sizeof (getfamily->sin_addr),
00467                          0);
00468     }
00469 #if defined ACE_HAS_IPV6
00470   else if (getfamily->sin_family == AF_INET6)
00471     {
00472       struct sockaddr_in6 *in6 = ACE_static_cast (struct sockaddr_in6*, addr);
00473       this->set_port_number (in6->sin6_port, 0);
00474       this->set_address (ACE_reinterpret_cast (const char*, &in6->sin6_addr),
00475                          sizeof (in6->sin6_addr),
00476                          0);
00477     }
00478 #endif // ACE_HAS_IPV6
00479 }
00480 
00481 // Creates a ACE_INET_Addr from a sockaddr_in structure.
00482 
00483 
00484 ACE_INET_Addr::ACE_INET_Addr (const sockaddr_in *addr, int len)
00485   : ACE_Addr (this->determine_type(), sizeof (inet_addr_))
00486 {
00487   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00488   this->reset();
00489   this->set (addr, len);
00490 }
00491 
00492 // Creates a ACE_INET_Addr from a PORT_NUMBER and an Internet address.
00493 
00494 
00495 ACE_INET_Addr::ACE_INET_Addr (u_short port_number,
00496                               ACE_UINT32 inet_address)
00497   : ACE_Addr (this->determine_type(), sizeof (inet_addr_))
00498 {
00499   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00500   this->reset();
00501   if (this->set (port_number, inet_address) == -1)
00502     ACE_ERROR ((LM_ERROR,
00503                 ACE_LIB_TEXT ("%p\n"),
00504                 ACE_LIB_TEXT ("ACE_INET_Addr::ACE_INET_Addr")));
00505 }
00506 
00507 // Creates a ACE_INET_Addr from a PORT_NAME and the remote
00508 // HOST_NAME.
00509 
00510 ACE_INET_Addr::ACE_INET_Addr (const char port_name[],
00511                               const char host_name[],
00512                               const char protocol[])
00513   : ACE_Addr (this->determine_type(), sizeof (inet_addr_))
00514 {
00515   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00516   this->reset();
00517   if (this->set (port_name,
00518                  host_name,
00519                  protocol) == -1)
00520     ACE_ERROR ((LM_ERROR,
00521                 ACE_LIB_TEXT ("ACE_INET_Addr::ACE_INET_Addr")));
00522 }
00523 
00524 #if defined (ACE_HAS_WCHAR)
00525 ACE_INET_Addr::ACE_INET_Addr (const wchar_t port_name[],
00526                               const wchar_t host_name[],
00527                               const wchar_t protocol[])
00528   : ACE_Addr (this->determine_type(), sizeof (inet_addr_))
00529 {
00530   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00531   this->reset();
00532   if (this->set (port_name,
00533                  host_name,
00534                  protocol) == -1)
00535     ACE_ERROR ((LM_ERROR,
00536                 ACE_LIB_TEXT ("ACE_INET_Addr::ACE_INET_Addr")));
00537 }
00538 #endif /* ACE_HAS_WCHAR */
00539 
00540 // Creates a ACE_INET_Addr from a PORT_NAME and an Internet address.
00541 
00542 
00543 ACE_INET_Addr::ACE_INET_Addr (const char port_name[],
00544                               ACE_UINT32 inet_address,
00545                               const char protocol[])
00546   : ACE_Addr (this->determine_type(), sizeof (inet_addr_))
00547 {
00548   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00549   this->reset();
00550   if (this->set (port_name,
00551                  inet_address,
00552                  protocol) == -1)
00553     ACE_ERROR ((LM_ERROR,
00554                 ACE_LIB_TEXT ("ACE_INET_Addr::ACE_INET_Addr")));
00555 }
00556 
00557 #if defined (ACE_HAS_WCHAR)
00558 ACE_INET_Addr::ACE_INET_Addr (const wchar_t port_name[],
00559                               ACE_UINT32 inet_address,
00560                               const wchar_t protocol[])
00561   : ACE_Addr (this->determine_type(), sizeof (inet_addr_))
00562 {
00563   ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
00564   this->reset();
00565   if (this->set (port_name,
00566                  inet_address,
00567                  protocol) == -1)
00568     ACE_ERROR ((LM_ERROR,
00569                 ACE_LIB_TEXT ("ACE_INET_Addr::ACE_INET_Addr")));
00570 }
00571 #endif /* ACE_HAS_WCHAR */
00572 
00573 int
00574 ACE_INET_Addr::get_host_name (char hostname[],
00575                               size_t len) const
00576 {
00577   ACE_TRACE ("ACE_INET_Addr::get_host_name");
00578 
00579   int result;
00580   if (len > 1)
00581     {
00582       result = get_host_name_i(hostname,len);
00583       if (result < 0)
00584         {
00585           if (result == -2)
00586             {
00587               result = -1;
00588               // We know that hostname is nul-terminated
00589             }
00590           else
00591             {
00592               //result == -1;
00593               // This could be worse than hostname[len -1] = '\0'?
00594               hostname[0] = '\0';
00595             }
00596         }
00597     }
00598   else
00599     {
00600       if (len == 1)
00601         {
00602           hostname[0] = '\0';
00603         }
00604       result = -1;
00605     }
00606 
00607   return result;
00608 }
00609 
00610 #if defined (ACE_HAS_WCHAR)
00611 int
00612 ACE_INET_Addr::get_host_name (wchar_t hostname[],
00613                               size_t len) const
00614 {
00615   ACE_TRACE ("ACE_INET_Addr::get_host_name");
00616 
00617   char char_hostname [MAXHOSTNAMELEN + 1];
00618 
00619   // We have a build in limitation of MAXHOSTNAMELEN
00620   if (len > MAXHOSTNAMELEN + 1)
00621     len = MAXHOSTNAMELEN + 1;
00622 
00623   // Call the char version
00624   int result = this->get_host_name (char_hostname, len);
00625 
00626   // And copy it over, if successful
00627   if (result == 0)
00628     ACE_OS_String::strcpy (hostname,
00629                            ACE_Ascii_To_Wide (char_hostname).wchar_rep ());
00630 
00631   return result;
00632 }
00633 #endif /* ACE_HAS_WCHAR */
00634 
00635 // Return the character representation of the hostname.
00636 
00637 const char *
00638 ACE_INET_Addr::get_host_name (void) const
00639 {
00640   ACE_TRACE ("ACE_INET_Addr::get_host_name");
00641 
00642   static char name[MAXHOSTNAMELEN + 1];
00643   if (this->get_host_name (name, MAXHOSTNAMELEN + 1) == -1)
00644     ACE_OS::strcpy (name, "<unknown>");
00645   return name;
00646 }
00647 
00648 void
00649 ACE_INET_Addr::set_port_number (u_short port_number,
00650                                 int encode)
00651 {
00652   ACE_TRACE ("ACE_INET_Addr::set_port_number");
00653 
00654   if (encode)
00655     port_number = htons (port_number);
00656 
00657 #if defined (ACE_HAS_IPV6)
00658   if (this->get_type () == AF_INET6)
00659     this->inet_addr_.in6_.sin6_port = port_number;
00660   else
00661 #endif /* ACE_HAS_IPV6 */
00662   this->inet_addr_.in4_.sin_port = port_number;
00663 }
00664 
00665 // returns -2 when the hostname is truncated
00666 int
00667 ACE_INET_Addr::get_host_name_i (char hostname[], size_t len) const
00668 {
00669   ACE_TRACE ("ACE_INET_Addr::get_host_name_i");
00670 
00671 #if defined (ACE_HAS_IPV6)
00672   if ((this->get_type () == PF_INET6 &&
00673        0 == ACE_OS_String::memcmp (&this->inet_addr_.in6_.sin6_addr,
00674                                    &in6addr_any,
00675                                    sizeof (this->inet_addr_.in6_.sin6_addr)))
00676       ||
00677       (this->get_type () == PF_INET &&
00678        this->inet_addr_.in4_.sin_addr.s_addr == INADDR_ANY))
00679 #else
00680   if (this->inet_addr_.in4_.sin_addr.s_addr == INADDR_ANY)
00681 #endif /* ACE_HAS_IPV6 */
00682     {
00683       if (ACE_OS::hostname (hostname, len) == -1)
00684         return -1;
00685       else
00686         return 0;
00687     }
00688   else
00689     {
00690 #if defined (VXWORKS)
00691       ACE_UNUSED_ARG (len);
00692       int error =
00693         ::hostGetByAddr ((int) this->inet_addr_.in4_.sin_addr.s_addr,
00694                          hostname);
00695       if (error == OK)
00696         return 0;
00697       else
00698         {
00699           errno = error;
00700           return -1;
00701         }
00702 #else
00703 #  if defined (CHORUS) || (defined (DIGITAL_UNIX) && defined (__GNUC__))
00704       hostent *hp = ACE_OS::gethostbyaddr ((char *)this->ip_addr_pointer (),
00705                                            this->ip_addr_size (),
00706                                            this->get_type ());
00707 #  else
00708       int h_error;  // Not the same as errno!
00709       hostent hentry;
00710       ACE_HOSTENT_DATA buf;
00711       hostent *hp =
00712         ACE_OS::gethostbyaddr_r ((char *)this->ip_addr_pointer (),
00713                                  this->ip_addr_size (),
00714                                  this->get_type (),
00715                                  &hentry,
00716                                  buf,
00717                                  &h_error);
00718 #  endif /* CHORUS */
00719 
00720       if (hp == 0 || hp->h_name == 0)
00721         return -1;
00722 
00723       if (ACE_OS::strlen (hp->h_name) >= len)
00724         {
00725           // We know the length, so use memcpy
00726           if (len > 0)
00727             {
00728               ACE_OS::memcpy (hostname, hp->h_name, len - 1);
00729               hostname[len-1]= '\0';
00730             }
00731           errno = ENOSPC;
00732           return -2;  // -2 Means that we have a good string
00733           // Using errno looks ok, but ENOSPC could be set on
00734           // other places.
00735         }
00736 
00737       ACE_OS::strcpy (hostname, hp->h_name);
00738       return 0;
00739 #endif /* VXWORKS */
00740     }
00741 }
00742 
00743 int ACE_INET_Addr::set_address (const char *ip_addr,
00744                                 int len,
00745                                 int encode /* = 1 */)
00746 {
00747   ACE_TRACE ("ACE_INET_Addr::set_address");
00748   // This is really intended for IPv4. If the object is IPv4, or the type
00749   // hasn't been set but it's a 4-byte address, go ahead. If this is an
00750   // IPv6 object and <encode> is requested, refuse.
00751   if (encode && len != 4)
00752     {
00753       errno = EAFNOSUPPORT;
00754       return -1;
00755     }
00756 
00757   if (len == 4)
00758     {
00759       ACE_UINT32 ip4 = *ACE_reinterpret_cast (const ACE_UINT32 *, ip_addr);
00760       if (encode)
00761         ip4 = ACE_HTONL (ip4);
00762 
00763 
00764       if (this->get_type () == AF_INET) {
00765         this->base_set (AF_INET, sizeof (this->inet_addr_.in4_));
00766         this->inet_addr_.in4_.sin_family = AF_INET;
00767         this->set_size (sizeof (this->inet_addr_.in4_));
00768         ACE_OS_String::memcpy (&this->inet_addr_.in4_.sin_addr,
00769                                &ip4,
00770                                len);
00771       }
00772 #if defined (ACE_HAS_IPV6)
00773       // If given an IPv4 address to copy to an IPv6 object, map it to
00774       // an IPv4-mapped IPv6 address.
00775       else
00776         {
00777           this->base_set (AF_INET6, sizeof (this->inet_addr_.in6_));
00778           this->inet_addr_.in6_.sin6_family = AF_INET6;
00779           this->set_size (sizeof (this->inet_addr_.in6_));
00780           if (ip4 == INADDR_ANY)
00781             {
00782               in6_addr ip6 = in6addr_any;
00783               ACE_OS_String::memcpy (&this->inet_addr_.in6_.sin6_addr,
00784                                      &ip6,
00785                                      sizeof (ip6));
00786               return 0;
00787             }
00788           if (ip4 == INADDR_LOOPBACK)
00789             {
00790               in6_addr ip6 = in6addr_loopback;
00791               ACE_OS_String::memcpy (&this->inet_addr_.in6_.sin6_addr,
00792                                      &ip6,
00793                                      sizeof (ip6));
00794               return 0;
00795             }
00796 
00797           // Build up a 128 bit address.  An IPv4-mapped IPv6 address
00798           // is defined as 0:0:0:0:0:ffff:IPv4_address.  This is defined
00799           // in RFC 1884 */
00800           struct {
00801             ACE_UINT16 prefix[5];
00802             ACE_UINT16 ffff;
00803             ACE_UINT32 addr;
00804           } newaddress = {
00805             { 0,0,0,0,0 },
00806             0xffff,
00807             ip4
00808           };
00809 
00810           ACE_OS_String::memcpy (&this->inet_addr_.in6_.sin6_addr,
00811                                  &newaddress,
00812                                  sizeof (newaddress));
00813         }
00814 #endif /* ACE_HAS_IPV6 */
00815 
00816       return 0;
00817     }   /* end if (len == 4) */
00818 #if defined (ACE_HAS_IPV6)
00819   else if (len == 16)
00820     {
00821       if (this->get_type () != PF_INET6)
00822         {
00823           errno = EAFNOSUPPORT;
00824           return -1;
00825         }
00826       // We protect ourselves up above so IPv6 must be possible here.
00827       this->base_set (AF_INET6, sizeof (this->inet_addr_.in6_));
00828       this->inet_addr_.in6_.sin6_family = AF_INET6;
00829       ACE_OS_String::memcpy (&this->inet_addr_.in6_.sin6_addr, ip_addr, len);
00830 
00831       return 0;
00832     } /* end len == 16 */
00833   else
00834     {
00835       /* unknown or unsupported address length */
00836       errno = EAFNOSUPPORT;
00837       return -1;
00838     }
00839 
00840 #endif /* ACE_HAS_IPV6 */
00841 
00842   // Here with an unrecognized length.
00843   errno = EAFNOSUPPORT;
00844   return -1;
00845 
00846 }
00847 
00848 
00849 const char *
00850 ACE_INET_Addr::get_host_addr (char *dst, int size) const
00851 {
00852 #if defined (ACE_HAS_IPV6)
00853   if (this->get_type () == AF_INET6)
00854     {
00855       if (IN6_IS_ADDR_V4MAPPED (&this->inet_addr_.in6_.sin6_addr))
00856         {
00857           ACE_UINT32 addr;
00858           addr = this->get_ip_address();
00859           addr = ACE_HTONL (addr);
00860           return ACE_OS::inet_ntop (AF_INET, &addr, dst, size);
00861         }
00862 
00863       const char *ch = ACE_OS::inet_ntop (AF_INET6,
00864                                           &this->inet_addr_.in6_.sin6_addr,
00865                                           dst,
00866                                           size);
00867       return ch;
00868     }
00869 #endif /* ACE_HAS_IPV6 */
00870 
00871 #if defined (VXWORKS)
00872   // It would be nice to be able to encapsulate this into
00873   // ACE_OS::inet_ntoa(), but that would lead to either inefficiencies
00874   // on vxworks or lack of thread safety.
00875   //
00876   // So, we use the way that vxworks suggests.
00877   ACE_INET_Addr *ncthis = ACE_const_cast (ACE_INET_Addr *, this);
00878   inet_ntoa_b (this->inet_addr_.in4_.sin_addr, ncthis->buf_);
00879   return &buf_[0];
00880 #else /* VXWORKS */
00881   char *ch = ACE_OS::inet_ntoa (this->inet_addr_.in4_.sin_addr);
00882   ACE_OS::strsncpy (dst, ch, size);
00883   return ch;
00884 #endif
00885 }
00886 
00887 // Return the dotted Internet address.
00888 const char *
00889 ACE_INET_Addr::get_host_addr (void) const
00890 {
00891   ACE_TRACE ("ACE_INET_Addr::get_host_addr");
00892 #if defined (ACE_HAS_IPV6)
00893   static char buf[INET6_ADDRSTRLEN];
00894   return this->get_host_addr (buf, INET6_ADDRSTRLEN);
00895 #else
00896   return ACE_OS::inet_ntoa (this->inet_addr_.in4_.sin_addr);
00897 #endif
00898 }
00899 
00900 // Return the 4-byte IP address, converting it into host byte order.
00901 
00902 ACE_UINT32
00903 ACE_INET_Addr::get_ip_address (void) const
00904 {
00905   ACE_TRACE ("ACE_INET_Addr::get_ip_address");
00906 #if defined (ACE_HAS_IPV6)
00907   if (this->get_type () == AF_INET6)
00908     {
00909       if (IN6_IS_ADDR_V4MAPPED (&this->inet_addr_.in6_.sin6_addr) ||
00910           IN6_IS_ADDR_V4COMPAT (&this->inet_addr_.in6_.sin6_addr)    )
00911         {
00912           ACE_UINT32 addr;
00913           // Return the last 32 bits of the address
00914           char *thisaddrptr = (char*)this->ip_addr_pointer ();
00915           thisaddrptr += 128/8 - 32/8;
00916           ACE_OS_String::memcpy (&addr, thisaddrptr, sizeof (addr));
00917           return ACE_NTOHL (addr);
00918         }
00919 
00920       ACE_ERROR ((LM_ERROR,
00921                   ACE_LIB_TEXT ("ACE_INET_Addr::get_ip_address: address is a IPv6 address not IPv4\n")));
00922       errno = EAFNOSUPPORT;
00923       return 0;
00924     }
00925 #endif /* ACE_HAS_IPV6 */
00926   return ntohl (ACE_UINT32 (this->inet_addr_.in4_.sin_addr.s_addr));
00927 }

Generated on Mon Jun 16 11:19:53 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002