INET_Addr.cpp

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

Generated on Thu Nov 9 09:41:52 2006 for ACE by doxygen 1.3.6