1 // Defines the Internet domain address family address format.
2 #include "ace/INET_Addr.h"
4 #if !defined (__ACE_INLINE__)
5 #include "ace/INET_Addr.inl"
6 #endif /* __ACE_INLINE__ */
8 #include "ace/Log_Category.h"
9 #include "ace/OS_NS_stdio.h"
10 #include "ace/OS_NS_errno.h"
11 #include "ace/OS_NS_stdlib.h"
12 #include "ace/OS_Memory.h"
13 #include "ace/OS_NS_arpa_inet.h"
14 #include "ace/OS_NS_netdb.h"
15 #include "ace/OS_NS_unistd.h"
16 #include "ace/OS_NS_sys_socket.h"
17 #include "ace/Truncate.h"
18 #if defined (ACE_HAS_ALLOC_HOOKS)
19 # include "ace/Malloc_Base.h"
20 #endif /* ACE_HAS_ALLOC_HOOKS */
22 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
24 ACE_ALLOC_HOOK_DEFINE(ACE_INET_Addr
)
26 // Transform the current address into string format.
29 ACE_INET_Addr::addr_to_string (ACE_TCHAR s
[],
31 int ipaddr_format
) const
33 ACE_TRACE ("ACE_INET_Addr::addr_to_string");
35 // XXX Can we (should we) include the scope id for IPv6 addresses?
36 char hoststr
[MAXHOSTNAMELEN
+1];
39 if (ipaddr_format
== 0)
40 result
= (this->get_host_name (hoststr
, MAXHOSTNAMELEN
+1) == 0);
42 result
= (this->get_host_addr (hoststr
, MAXHOSTNAMELEN
+1) != 0);
48 ACE_OS::strlen (hoststr
)
49 + 5 // ACE_OS::strlen ("65535"), Assuming the max port number.
50 + 1 // sizeof (':'), addr/port sep
51 + 1; // sizeof ('\0'), terminating NUL
52 ACE_TCHAR
const *format
= ACE_TEXT("%") ACE_TEXT_PRIs
ACE_TEXT(":%d");
53 #if defined (ACE_HAS_IPV6)
54 if (ACE_OS::strchr (hoststr
, ACE_TEXT (':')) != 0)
56 total_len
+= 2; // ACE_OS::strlen ("[]") IPv6 addr frames
57 format
= ACE_TEXT("[%") ACE_TEXT_PRIs
ACE_TEXT("]:%d");
59 #endif // ACE_HAS_IPV6
64 ACE_OS::snprintf (s
, size
, format
,
65 ACE_TEXT_CHAR_TO_TCHAR (hoststr
),
66 this->get_port_number ());
71 ACE_INET_Addr::dump () const
73 #if defined (ACE_HAS_DUMP)
74 ACE_TRACE ("ACE_INET_Addr::dump");
76 ACELIB_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
78 ACE_TCHAR s
[ACE_MAX_FULLY_QUALIFIED_NAME_LEN
+ 16];
79 this->addr_to_string(s
, ACE_MAX_FULLY_QUALIFIED_NAME_LEN
+ 16);
80 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("%s"), s
));
81 ACELIB_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
82 #endif /* ACE_HAS_DUMP */
85 // Compare two addresses for inequality.
88 ACE_INET_Addr::operator != (const ACE_INET_Addr
&sap
) const
90 ACE_TRACE ("ACE_INET_Addr::operator !=");
91 return !((*this) == sap
);
94 // Compare two addresses for equality.
97 ACE_INET_Addr::operator == (const ACE_INET_Addr
&sap
) const
99 ACE_TRACE ("ACE_INET_Addr::operator ==");
101 if (this->get_type () != sap
.get_type ()
102 || this->get_size () != sap
.get_size ())
105 return (ACE_OS::memcmp (&this->inet_addr_
,
107 this->get_size ()) == 0);
111 ACE_INET_Addr::is_ip_equal (const ACE_INET_Addr
&sap
) const
113 if (this->get_type () != sap
.get_type ()
114 || this->get_size () != sap
.get_size ())
117 #if defined (ACE_HAS_IPV6)
118 if (this->get_type () == PF_INET6
)
120 const unsigned int *addr
=
121 reinterpret_cast<const unsigned int*>(this->ip_addr_pointer());
122 const unsigned int *saddr
=
123 reinterpret_cast<const unsigned int*>(sap
.ip_addr_pointer());
124 return (addr
[0] == saddr
[0] &&
125 addr
[1] == saddr
[1] &&
126 addr
[2] == saddr
[2] &&
127 addr
[3] == saddr
[3]);
130 #endif /* ACE_HAS_IPV6 */
131 return this->get_ip_address () == sap
.get_ip_address();
135 ACE_INET_Addr::hash () const
137 #if defined (ACE_HAS_IPV6)
138 if (this->get_type () == PF_INET6
)
140 const unsigned int *addr
= (const unsigned int*)this->ip_addr_pointer();
141 return addr
[0] + addr
[1] + addr
[2] + addr
[3] + this->get_port_number();
144 #endif /* ACE_HAS_IPV6 */
145 return this->get_ip_address () + this->get_port_number ();
149 ACE_INET_Addr::next ()
151 if (this->inet_addrs_
.empty () ||
152 this->inet_addrs_iter_
== this->inet_addrs_
.end ())
155 union ip46 next_a
= *this->inet_addrs_iter_
++;
156 this->set_addr (&next_a
, sizeof (next_a
));
161 ACE_INET_Addr::reset ()
163 this->inet_addrs_iter_
= this->inet_addrs_
.begin ();
167 ACE_INET_Addr::ACE_INET_Addr ()
168 : ACE_Addr (determine_type (), sizeof (inet_addr_
))
170 // ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
175 ACE_INET_Addr::operator= (const ACE_INET_Addr
& rhs
)
183 ACE_INET_Addr::set (const ACE_INET_Addr
&sa
)
185 ACE_TRACE ("ACE_INET_Addr::set");
187 if (sa
.get_type () == AF_ANY
)
188 // Ugh, this is really a base class, so don't copy it.
189 ACE_OS::memset (&this->inet_addr_
, 0, sizeof (this->inet_addr_
));
192 // It's ok to make the copy.
193 ACE_OS::memcpy (&this->inet_addr_
,
197 this->set_type (sa
.get_type());
198 this->set_size (sa
.get_size());
199 this->inet_addrs_
= sa
.inet_addrs_
;
206 // Transform the string into the current addressing format.
209 ACE_INET_Addr::string_to_addr (const char s
[], int address_family
)
211 ACE_TRACE ("ACE_INET_Addr::string_to_addr");
216 // Need to make a duplicate since we'll be overwriting the string.
217 ACE_ALLOCATOR_RETURN (ip_buf
,
221 // We use strrchr because of IPv6 addresses.
222 char *port_p
= ACE_OS::strrchr (ip_addr
, ':');
223 #if defined (ACE_HAS_IPV6)
224 // Check for extended IPv6 format : '[' <ipv6 address> ']' ':' <port>
225 if (ip_addr
[0] == '[')
227 // find closing bracket
228 char *cp_pos
= ACE_OS::strchr (ip_addr
, ']');
229 // check for port separator after closing bracket
230 // if not found leave it, error will come later
233 *cp_pos
= '\0'; // blank out ']'
234 ++ip_addr
; // skip over '['
235 if (cp_pos
[1] == ':')
238 port_p
= cp_pos
; // leads to error on missing port
241 #endif /* ACE_HAS_IPV6 */
243 if (port_p
== 0) // Assume it's a port number.
246 long const port
= ACE_OS::strtol (ip_addr
, &endp
, 10);
248 if (*endp
== '\0') // strtol scanned the entire string - all digits
250 if (port
< 0 || port
> ACE_MAX_DEFAULT_PORT
)
253 result
= this->set (u_short (port
), ACE_UINT32 (INADDR_ANY
));
256 result
= this->set (ip_addr
, ACE_UINT32 (INADDR_ANY
));
260 *port_p
= '\0'; ++port_p
; // skip over ':'
263 long port
= ACE_OS::strtol (port_p
, &endp
, 10);
265 if (*endp
== '\0') // strtol scanned the entire string - all digits
267 if (port
< 0 || port
> ACE_MAX_DEFAULT_PORT
)
270 result
= this->set (u_short (port
), ip_addr
, 1, address_family
);
273 result
= this->set (port_p
, ip_addr
);
276 #if defined (ACE_HAS_ALLOC_HOOKS)
277 ACE_Allocator::instance()->free (ACE_MALLOC_T (ip_buf
));
279 ACE_OS::free (ACE_MALLOC_T (ip_buf
));
280 #endif /* ACE_HAS_ALLOC_HOOKS */
285 ACE_INET_Addr::set (const char address
[], int address_family
)
287 ACE_TRACE ("ACE_INET_Addr::set");
289 return this->string_to_addr (address
, address_family
);
292 ACE_INET_Addr::ACE_INET_Addr (const char address
[], int address_family
)
293 : ACE_Addr (determine_type (), sizeof (inet_addr_
))
295 ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
296 this->set (address
, address_family
);
299 #if defined (ACE_HAS_WCHAR)
300 ACE_INET_Addr::ACE_INET_Addr (const wchar_t address
[], int address_family
)
301 : ACE_Addr (determine_type (), sizeof (inet_addr_
))
303 ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
304 this->set (address
, address_family
);
307 #endif /* ACE_HAS_WCHAR */
311 ACE_INET_Addr::ACE_INET_Addr (const ACE_INET_Addr
&sa
)
312 : ACE_Addr (sa
.get_type (), sa
.get_size())
314 ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
318 // Initializes a ACE_INET_Addr from a PORT_NUMBER and a 32 bit Internet
321 ACE_INET_Addr::set (u_short port_number
,
322 ACE_UINT32 inet_address
,
326 ACE_TRACE ("ACE_INET_Addr::set");
328 this->set_address (reinterpret_cast<const char *> (&inet_address
),
331 this->set_port_number (port_number
, encode
);
336 // Initializes a ACE_INET_Addr from a PORT_NUMBER and the remote
339 ACE_INET_Addr::set (u_short port_number
,
340 const char host_name
[],
344 ACE_TRACE ("ACE_INET_Addr::set");
346 // Yow, someone gave us a NULL host_name!
355 #if defined ACE_HAS_IPV6 && defined ACE_USES_IPV4_IPV6_MIGRATION
356 if (address_family
== AF_UNSPEC
&& !ACE::ipv6_enabled ())
357 address_family
= AF_INET
;
358 #endif /* ACE_HAS_IPV6 && ACE_USES_IPV4_IPV6_MIGRATION */
361 if (address_family
== AF_UNSPEC
&& ACE::ipv6_enabled ())
362 address_family
= AF_INET6
;
364 if (address_family
!= AF_INET
365 && ACE_OS::inet_pton (AF_INET6
, host_name
,
366 &this->inet_addr_
.in6_
.sin6_addr
) == 1)
368 this->base_set (AF_INET6
, sizeof this->inet_addr_
.in4_
);
369 # ifdef ACE_HAS_SOCKADDR_IN6_SIN6_LEN
370 this->inet_addr_
.in6_
.sin6_len
= sizeof this->inet_addr_
.in6_
;
372 this->inet_addr_
.in6_
.sin6_family
= AF_INET6
;
373 this->set_size (sizeof this->inet_addr_
.in6_
);
374 this->set_type (AF_INET6
);
375 this->set_port_number (port_number
, encode
);
379 address_family
= AF_INET
;
380 #endif /* ACE_HAS_IPV6 */
382 if (ACE_OS::inet_pton (AF_INET
, host_name
,
383 &this->inet_addr_
.in4_
.sin_addr
) == 1)
385 this->base_set (AF_INET
, sizeof this->inet_addr_
.in4_
);
386 #ifdef ACE_HAS_SOCKADDR_IN_SIN_LEN
387 this->inet_addr_
.in4_
.sin_len
= sizeof this->inet_addr_
.in4_
;
389 this->inet_addr_
.in4_
.sin_family
= AF_INET
;
390 this->set_size (sizeof this->inet_addr_
.in4_
);
391 this->set_type (AF_INET
);
392 this->set_port_number (port_number
, encode
);
397 ACE_OS::memset (&hints
, 0, sizeof hints
);
398 hints
.ai_family
= address_family
;
399 // The ai_flags used to contain AI_ADDRCONFIG as well but that prevented
400 // lookups from completing if there is no, or only a loopback, IPv6
401 // interface configured. See Bugzilla 4211 for more info.
403 hints
.ai_flags
= AI_V4MAPPED
;
404 #if defined(ACE_HAS_IPV6) && defined(AI_ALL)
405 // Without AI_ALL, Windows machines exhibit inconsistent behaviors on
406 // difference machines we have tested.
407 hints
.ai_flags
|= AI_ALL
;
410 // Note - specify the socktype here to avoid getting multiple entries
411 // returned with the same address for different socket types or
412 // protocols. If this causes a problem for some reason (an address that's
413 // available for TCP but not UDP, or vice-versa) this will need to change
414 // back to unrestricted hints and weed out the duplicate addresses by
415 // searching this->inet_addrs_ which would slow things down.
416 hints
.ai_socktype
= SOCK_STREAM
;
419 const int error
= ACE_OS::getaddrinfo (host_name
, 0, &hints
, &res
);
427 this->set_type (res
->ai_family
);
429 for (addrinfo
*curr
= res
; curr
; curr
= curr
->ai_next
)
432 ACE_OS::memcpy (&addr
, curr
->ai_addr
, curr
->ai_addrlen
);
434 if (curr
->ai_family
== AF_INET6
)
435 addr
.in6_
.sin6_port
= encode
? ACE_NTOHS (port_number
) : port_number
;
438 addr
.in4_
.sin_port
= encode
? ACE_NTOHS (port_number
) : port_number
;
439 this->inet_addrs_
.push_back (addr
);
442 ACE_OS::freeaddrinfo (res
);
447 /// Helper function to get a port number from a port name.
448 static int get_port_number_from_name (const char port_name
[],
449 const char protocol
[])
451 // Maybe port_name is directly a port number?
453 long port_number
= ACE_OS::strtol (port_name
, &endp
, 10);
457 // port_name was really a number, and nothing else.
459 // Check for overflow.
460 if (port_number
< 0 || port_number
> ACE_MAX_DEFAULT_PORT
)
463 // Return the port number. NOTE: this number must
464 // be returned in network byte order!
465 u_short n
= static_cast<u_short
> (port_number
);
470 // We try to resolve port number from its name.
472 #if defined (ACE_LACKS_GETSERVBYNAME)
473 ACE_UNUSED_ARG (port_name
);
474 ACE_UNUSED_ARG (protocol
);
477 ACE_SERVENT_DATA buf
;
478 servent
*sp
= ACE_OS::getservbyname_r (port_name
,
483 port_number
= sp
->s_port
;
484 #endif /* ACE_LACKS_GETSERVBYNAME */
489 /// Initializes a ACE_INET_Addr from a @a port_name and the remote
492 ACE_INET_Addr::set (const char port_name
[],
493 const char host_name
[],
494 const char protocol
[])
496 ACE_TRACE ("ACE_INET_Addr::set");
499 int const port_number
= get_port_number_from_name (port_name
, protocol
);
500 if (port_number
== -1)
502 ACE_NOTSUP_RETURN (-1);
505 int address_family
= PF_UNSPEC
;
506 if (ACE_OS::strcmp(protocol
, "tcp") == 0)
507 address_family
= AF_INET
;
509 # if defined (ACE_HAS_IPV6)
510 if (ACE_OS::strcmp (protocol
, "tcp6") == 0)
511 address_family
= AF_INET6
;
512 # endif /* ACE_HAS_IPV6 */
514 return this->set (static_cast<u_short
> (port_number
),
515 host_name
, 0, address_family
);
518 /// Initializes a ACE_INET_Addr from a @a port_name and a 32 bit
519 /// Internet address.
521 ACE_INET_Addr::set (const char port_name
[],
522 ACE_UINT32 inet_address
,
523 const char protocol
[])
525 ACE_TRACE ("ACE_INET_Addr::set");
528 int const port_number
= get_port_number_from_name (port_name
, protocol
);
529 if (port_number
== -1)
531 ACE_NOTSUP_RETURN (-1);
534 return this->set (static_cast<u_short
> (port_number
),
538 // Creates a ACE_INET_Addr from a PORT_NUMBER and the remote
540 ACE_INET_Addr::ACE_INET_Addr (u_short port_number
,
541 const char host_name
[],
543 : ACE_Addr (determine_type (), sizeof (inet_addr_
))
545 ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
546 ACE_OS::memset (&this->inet_addr_
, 0, sizeof (this->inet_addr_
));
547 if (this->set (port_number
,
550 address_family
) == -1)
551 ACELIB_ERROR ((LM_ERROR
,
552 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr: %p\n"),
553 ACE_TEXT_CHAR_TO_TCHAR ((host_name
== 0) ?
554 "<unknown>" : host_name
)));
557 #if defined (ACE_HAS_WCHAR)
558 ACE_INET_Addr::ACE_INET_Addr (u_short port_number
,
559 const wchar_t host_name
[],
561 : ACE_Addr (determine_type (), sizeof (inet_addr_
))
563 ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
564 ACE_OS::memset (&this->inet_addr_
, 0, sizeof (this->inet_addr_
));
565 if (this->set (port_number
,
568 address_family
) == -1)
569 ACELIB_ERROR ((LM_ERROR
,
570 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr: %p\n"),
571 ACE_TEXT_WCHAR_TO_TCHAR ((host_name
== 0) ?
572 ACE_TEXT_WIDE ("<unknown>") :
575 #endif /* ACE_HAS_WCHAR */
577 // Creates a ACE_INET_Addr from a sockaddr_in structure.
579 ACE_INET_Addr::set (const sockaddr_in
*addr
, int len
)
581 ACE_TRACE ("ACE_INET_Addr::set");
584 if (addr
->sin_family
== AF_INET
)
586 int const maxlen
= static_cast<int> (sizeof (this->inet_addr_
.in4_
));
589 ACE_OS::memcpy (&this->inet_addr_
.in4_
, addr
, len
);
590 this->base_set (AF_INET
, len
);
593 #if defined (ACE_HAS_IPV6)
594 else if (addr
->sin_family
== AF_INET6
)
596 int const maxlen
= static_cast<int> (sizeof (this->inet_addr_
.in6_
));
599 ACE_OS::memcpy (&this->inet_addr_
.in6_
, addr
, len
);
600 this->base_set (AF_INET6
, len
);
603 #endif /* ACE_HAS_IPV6 */
605 errno
= EAFNOSUPPORT
;
609 // Return the address.
611 ACE_INET_Addr::get_addr () const
613 ACE_TRACE ("ACE_INET_Addr::get_addr");
614 return (void*)&this->inet_addr_
;
618 ACE_INET_Addr::set_addr (const void *addr
, int len
)
620 this->set_addr (addr
, len
, 0);
623 // Set a pointer to the address.
625 ACE_INET_Addr::set_addr (const void *addr
, int /* len */, int map
)
627 ACE_TRACE ("ACE_INET_Addr::set_addr");
628 const struct sockaddr_in
*getfamily
=
629 static_cast<const struct sockaddr_in
*> (addr
);
631 if (getfamily
->sin_family
== AF_INET
)
633 #if defined (ACE_HAS_IPV6)
635 this->set_type (AF_INET6
);
637 #endif /* ACE_HAS_IPV6 */
638 this->set_type (AF_INET
);
639 this->set_port_number (getfamily
->sin_port
, 0);
640 this->set_address (reinterpret_cast<const char*> (&getfamily
->sin_addr
),
641 sizeof (getfamily
->sin_addr
),
644 #if defined (ACE_HAS_IPV6)
645 else if (getfamily
->sin_family
== AF_INET6
)
647 const struct sockaddr_in6
*in6
=
648 static_cast<const struct sockaddr_in6
*> (addr
);
649 this->set_port_number (in6
->sin6_port
, 0);
650 this->set_address (reinterpret_cast<const char*> (&in6
->sin6_addr
),
651 sizeof (in6
->sin6_addr
),
653 this->inet_addr_
.in6_
.sin6_scope_id
= in6
->sin6_scope_id
;
655 #endif // ACE_HAS_IPV6
658 // Creates a ACE_INET_Addr from a sockaddr_in structure.
659 ACE_INET_Addr::ACE_INET_Addr (const sockaddr_in
*addr
, int len
)
660 : ACE_Addr (determine_type (), sizeof (inet_addr_
))
662 ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
663 this->set (addr
, len
);
666 // Creates a ACE_INET_Addr from a PORT_NUMBER and an Internet address.
667 ACE_INET_Addr::ACE_INET_Addr (u_short port_number
,
668 ACE_UINT32 inet_address
)
669 : ACE_Addr (determine_type (), sizeof (inet_addr_
))
671 ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
672 if (this->set (port_number
, inet_address
) == -1)
673 ACELIB_ERROR ((LM_ERROR
,
675 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr")));
678 // Creates a ACE_INET_Addr from a PORT_NAME and the remote
680 ACE_INET_Addr::ACE_INET_Addr (const char port_name
[],
681 const char host_name
[],
682 const char protocol
[])
683 : ACE_Addr (determine_type (), sizeof (inet_addr_
))
685 ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
686 if (this->set (port_name
,
689 ACELIB_ERROR ((LM_ERROR
,
690 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr")));
693 #if defined (ACE_HAS_WCHAR)
694 ACE_INET_Addr::ACE_INET_Addr (const wchar_t port_name
[],
695 const wchar_t host_name
[],
696 const wchar_t protocol
[])
697 : ACE_Addr (determine_type (), sizeof (inet_addr_
))
699 ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
700 if (this->set (port_name
,
703 ACELIB_ERROR ((LM_ERROR
,
704 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr")));
706 #endif /* ACE_HAS_WCHAR */
708 // Creates a ACE_INET_Addr from a PORT_NAME and an Internet address.
709 ACE_INET_Addr::ACE_INET_Addr (const char port_name
[],
710 ACE_UINT32 inet_address
,
711 const char protocol
[])
712 : ACE_Addr (determine_type (), sizeof (inet_addr_
))
714 ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
715 if (this->set (port_name
,
716 ACE_HTONL (inet_address
),
718 ACELIB_ERROR ((LM_ERROR
,
719 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr")));
722 #if defined (ACE_HAS_WCHAR)
723 ACE_INET_Addr::ACE_INET_Addr (const wchar_t port_name
[],
724 ACE_UINT32 inet_address
,
725 const wchar_t protocol
[])
726 : ACE_Addr (determine_type (), sizeof (inet_addr_
))
728 ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
729 if (this->set (port_name
,
730 ACE_HTONL (inet_address
),
732 ACELIB_ERROR ((LM_ERROR
,
733 ACE_TEXT ("ACE_INET_Addr::ACE_INET_Addr")));
735 #endif /* ACE_HAS_WCHAR */
737 ACE_INET_Addr::~ACE_INET_Addr ()
742 ACE_INET_Addr::get_host_name (char hostname
[],
745 ACE_TRACE ("ACE_INET_Addr::get_host_name");
750 result
= this->get_host_name_i (hostname
,len
);
754 // We know that hostname is nul-terminated
759 // This could be worse than hostname[len -1] = '\0'?
774 #if defined (ACE_HAS_WCHAR)
776 ACE_INET_Addr::get_host_name (wchar_t hostname
[],
779 ACE_TRACE ("ACE_INET_Addr::get_host_name");
781 char char_hostname
[MAXHOSTNAMELEN
+ 1];
783 // We have a build in limitation of MAXHOSTNAMELEN
784 if (len
> MAXHOSTNAMELEN
+ 1)
785 len
= MAXHOSTNAMELEN
+ 1;
787 // Call the char version
788 int const result
= this->get_host_name (char_hostname
, len
);
790 // And copy it over, if successful
792 ACE_OS::strcpy (hostname
,
793 ACE_Ascii_To_Wide (char_hostname
).wchar_rep ());
797 #endif /* ACE_HAS_WCHAR */
799 // Return the character representation of the hostname.
802 ACE_INET_Addr::get_host_name () const
804 ACE_TRACE ("ACE_INET_Addr::get_host_name");
806 static char name
[MAXHOSTNAMELEN
+ 1];
807 if (this->get_host_name (name
, MAXHOSTNAMELEN
+ 1) == -1)
808 ACE_OS::strcpy (name
, "<unknown>");
813 ACE_INET_Addr::set_port_number (u_short port_number
,
816 ACE_TRACE ("ACE_INET_Addr::set_port_number");
819 port_number
= ACE_HTONS (port_number
);
821 #if defined (ACE_HAS_IPV6)
822 if (this->get_type () == AF_INET6
)
823 this->inet_addr_
.in6_
.sin6_port
= port_number
;
825 #endif /* ACE_HAS_IPV6 */
826 this->inet_addr_
.in4_
.sin_port
= port_number
;
828 if (this->inet_addrs_
.empty ())
830 for (std::vector
<union ip46
>::iterator i
= this->inet_addrs_
.begin ();
831 i
!= this->inet_addrs_
.end ();
834 #if defined (ACE_HAS_IPV6)
835 if (this->get_type () == AF_INET6
)
836 i
->in6_
.sin6_port
= port_number
;
838 #endif /* ACE_HAS_IPV6 */
839 i
->in4_
.sin_port
= port_number
;
843 // returns -2 when the hostname is truncated
845 ACE_INET_Addr::get_host_name_i (char hostname
[], size_t len
) const
847 ACE_TRACE ("ACE_INET_Addr::get_host_name_i");
849 #if defined (ACE_HAS_IPV6)
850 if ((this->get_type () == PF_INET6
&&
851 0 == ACE_OS::memcmp (&this->inet_addr_
.in6_
.sin6_addr
,
853 sizeof (this->inet_addr_
.in6_
.sin6_addr
)))
855 (this->get_type () == PF_INET
&&
856 this->inet_addr_
.in4_
.sin_addr
.s_addr
== INADDR_ANY
))
858 if (this->inet_addr_
.in4_
.sin_addr
.s_addr
== INADDR_ANY
)
859 #endif /* ACE_HAS_IPV6 */
860 return (ACE_OS::hostname (hostname
, len
) == -1) ? -1 : 0;
862 const ACE_SOCKET_LEN addr_size
=
864 (this->get_type () == PF_INET6
) ? sizeof (sockaddr_in6
) :
866 sizeof (sockaddr_in
);
868 const int res
= ACE_OS::getnameinfo ((const sockaddr
*) this->get_addr (),
870 static_cast<ACE_SOCKET_LEN
> (len
),
872 return (res
== 0) ? 0 : -1;
875 int ACE_INET_Addr::set_address (const char *ip_addr
,
877 int encode
/* = 1 */,
880 ACE_TRACE ("ACE_INET_Addr::set_address");
881 // This is really intended for IPv4. If the object is IPv4, or the type
882 // hasn't been set but it's a 4-byte address, go ahead. If this is an
883 // IPv6 object and <encode> is requested, refuse.
884 if (encode
&& len
!= 4)
886 errno
= EAFNOSUPPORT
;
892 ACE_UINT32 ip4
= *reinterpret_cast<const ACE_UINT32
*> (ip_addr
);
894 ip4
= ACE_HTONL (ip4
);
897 if (this->get_type () == AF_INET
&& map
== 0) {
898 this->base_set (AF_INET
, sizeof (this->inet_addr_
.in4_
));
899 #ifdef ACE_HAS_SOCKADDR_IN_SIN_LEN
900 this->inet_addr_
.in4_
.sin_len
= sizeof (this->inet_addr_
.in4_
);
902 this->inet_addr_
.in4_
.sin_family
= AF_INET
;
903 this->set_size (sizeof (this->inet_addr_
.in4_
));
904 ACE_OS::memcpy (&this->inet_addr_
.in4_
.sin_addr
,
908 #if defined (ACE_HAS_IPV6)
911 // this->set_type (AF_INET);
912 this->base_set (AF_INET
, sizeof (this->inet_addr_
.in4_
));
913 #ifdef ACE_HAS_SOCKADDR_IN_SIN_LEN
914 this->inet_addr_
.in4_
.sin_len
= sizeof (this->inet_addr_
.in4_
);
916 this->inet_addr_
.in4_
.sin_family
= AF_INET
;
917 this->set_size (sizeof (this->inet_addr_
.in4_
));
918 ACE_OS::memcpy (&this->inet_addr_
.in4_
.sin_addr
,
921 // If given an IPv4 address to copy to an IPv6 object, map it to
922 // an IPv4-mapped IPv6 address.
925 this->base_set (AF_INET6
, sizeof (this->inet_addr_
.in6_
));
926 #ifdef ACE_HAS_SOCKADDR_IN6_SIN6_LEN
927 this->inet_addr_
.in6_
.sin6_len
= sizeof (this->inet_addr_
.in6_
);
929 this->inet_addr_
.in6_
.sin6_family
= AF_INET6
;
930 this->set_size (sizeof (this->inet_addr_
.in6_
));
931 if (ip4
== ACE_HTONL (INADDR_ANY
))
933 in6_addr
const ip6
= in6addr_any
;
934 ACE_OS::memcpy (&this->inet_addr_
.in6_
.sin6_addr
,
941 // Build up a 128 bit address. An IPv4-mapped IPv6 address
942 // is defined as 0:0:0:0:0:ffff:IPv4_address. This is defined
944 ACE_OS::memset (&this->inet_addr_
.in6_
.sin6_addr
, 0, 16);
945 this->inet_addr_
.in6_
.sin6_addr
.s6_addr
[10] =
946 this->inet_addr_
.in6_
.sin6_addr
.s6_addr
[11] = 0xff;
948 (&this->inet_addr_
.in6_
.sin6_addr
.s6_addr
[12], &ip4
, 4);
951 #endif /* ACE_HAS_IPV6 */
954 } /* end if (len == 4) */
955 #if defined (ACE_HAS_IPV6)
958 if (this->get_type () != PF_INET6
)
960 errno
= EAFNOSUPPORT
;
963 // We protect ourselves up above so IPv6 must be possible here.
964 this->base_set (AF_INET6
, sizeof (this->inet_addr_
.in6_
));
965 this->inet_addr_
.in6_
.sin6_family
= AF_INET6
;
966 #ifdef ACE_HAS_SOCKADDR_IN6_SIN6_LEN
967 this->inet_addr_
.in6_
.sin6_len
= sizeof (this->inet_addr_
.in6_
);
969 ACE_OS::memcpy (&this->inet_addr_
.in6_
.sin6_addr
, ip_addr
, len
);
971 } /* end len == 16 */
972 #endif /* ACE_HAS_IPV6 */
974 // Here with an unrecognized length.
975 errno
= EAFNOSUPPORT
;
979 #if (defined (ACE_LINUX) || defined (ACE_WIN32)) && defined (ACE_HAS_IPV6)
981 ACE_INET_Addr::set_interface (const char *intf_name
)
983 if (this->get_type () == PF_INET6
&&
984 (IN6_IS_ADDR_LINKLOCAL (&this->inet_addr_
.in6_
.sin6_addr
) ||
985 IN6_IS_ADDR_MC_LINKLOCAL (&this->inet_addr_
.in6_
.sin6_addr
)))
987 #if defined (ACE_LINUX)
988 this->inet_addr_
.in6_
.sin6_scope_id
=
989 ACE_OS::if_nametoindex (intf_name
);
991 this->inet_addr_
.in6_
.sin6_scope_id
=
992 intf_name
? ACE_OS::atoi (intf_name
) : 0;
994 // check to see if the interface lookup succeeded
995 if (this->inet_addr_
.in6_
.sin6_scope_id
!= 0)
1003 #endif /* ACE_LINUX && ACE_HAS_IPV6 */
1006 ACE_INET_Addr::get_host_addr (char *dst
, int size
) const
1008 #if defined (ACE_HAS_IPV6)
1009 if (this->get_type () == AF_INET6
)
1011 // mcorino@remedy.nl - Aug-26, 2005
1012 // I don't think this should be done because it results in a decimal address
1013 // representation which is not distinguishable from the IPv4 form which makes
1014 // it impossible to resolve back to an IPv6 INET_Addr without prior knowledge
1015 // that this was such an address to begin with.
1017 //if (IN6_IS_ADDR_V4MAPPED (&this->inet_addr_.in6_.sin6_addr))
1020 // addr = this->get_ip_address();
1021 // addr = ACE_HTONL (addr);
1022 // return ACE_OS::inet_ntop (AF_INET, &addr, dst, size);
1025 # if defined (ACE_WIN32)
1026 sockaddr
*sa
= reinterpret_cast<sockaddr
*>
1027 (const_cast<sockaddr_in6
*> (&this->inet_addr_
.in6_
));
1028 if (ACE_OS::getnameinfo (sa
, this->get_size (), dst
, size
,
1029 0, 0, // Don't want service name
1030 NI_NUMERICHOST
) == 0)
1032 ACE_OS::set_errno_to_wsa_last_error ();
1035 const char *ch
= ACE_OS::inet_ntop (AF_INET6
,
1036 &this->inet_addr_
.in6_
.sin6_addr
,
1039 #if defined (ACE_LINUX)
1040 if ((IN6_IS_ADDR_LINKLOCAL (&this->inet_addr_
.in6_
.sin6_addr
) ||
1041 IN6_IS_ADDR_MC_LINKLOCAL (&this->inet_addr_
.in6_
.sin6_addr
)) &&
1042 this->inet_addr_
.in6_
.sin6_scope_id
!= 0)
1045 ACE_OS::snprintf (scope_buf
, 32, "%%%u",
1046 this->inet_addr_
.in6_
.sin6_scope_id
);
1047 if ((ACE_OS::strlen (ch
)+ACE_OS::strlen (scope_buf
)) < (size_t)size
)
1049 ACE_OS::strcat (dst
, scope_buf
);
1054 # endif /* ACE_WIN32 */
1056 #endif /* ACE_HAS_IPV6 */
1058 return ACE_OS::inet_ntop (AF_INET
,
1059 &this->inet_addr_
.in4_
.sin_addr
,
1064 // Return the dotted Internet address.
1066 ACE_INET_Addr::get_host_addr () const
1068 ACE_TRACE ("ACE_INET_Addr::get_host_addr");
1069 #if defined (ACE_HAS_IPV6)
1070 static char buf
[INET6_ADDRSTRLEN
];
1071 return this->get_host_addr (buf
, INET6_ADDRSTRLEN
);
1072 #else /* ACE_HAS_IPV6 */
1073 static char buf
[INET_ADDRSTRLEN
];
1074 return this->get_host_addr (buf
, INET_ADDRSTRLEN
);
1075 #endif /* !ACE_HAS_IPV6 */
1078 // Return the 4-byte IP address, converting it into host byte order.
1080 ACE_INET_Addr::get_ip_address () const
1082 ACE_TRACE ("ACE_INET_Addr::get_ip_address");
1083 #if defined (ACE_HAS_IPV6)
1084 if (this->get_type () == AF_INET6
)
1086 if (IN6_IS_ADDR_V4MAPPED (&this->inet_addr_
.in6_
.sin6_addr
) ||
1087 IN6_IS_ADDR_V4COMPAT (&this->inet_addr_
.in6_
.sin6_addr
))
1090 // Return the last 32 bits of the address
1091 char *thisaddrptr
= (char*)this->ip_addr_pointer ();
1092 thisaddrptr
+= 128/8 - 32/8;
1093 ACE_OS::memcpy (&addr
, thisaddrptr
, sizeof (addr
));
1094 return ACE_NTOHL (addr
);
1097 ACELIB_ERROR ((LM_ERROR
,
1098 ACE_TEXT ("ACE_INET_Addr::get_ip_address: address is a IPv6 address not IPv4\n")));
1099 errno
= EAFNOSUPPORT
;
1102 #endif /* ACE_HAS_IPV6 */
1103 return ACE_NTOHL (ACE_UINT32 (this->inet_addr_
.in4_
.sin_addr
.s_addr
));
1106 ACE_END_VERSIONED_NAMESPACE_DECL