1 #include "ace/SOCK_Dgram.h"
3 #include "ace/Log_Category.h"
4 #include "ace/INET_Addr.h"
6 #include "ace/OS_NS_string.h"
7 #include "ace/OS_Memory.h"
8 #include "ace/OS_NS_ctype.h"
9 #include "ace/os_include/net/os_if.h"
10 #include "ace/Truncate.h"
11 #if defined (ACE_HAS_ALLOC_HOOKS)
12 # include "ace/Malloc_Base.h"
13 #endif /* ACE_HAS_ALLOC_HOOKS */
15 #if !defined (__ACE_INLINE__)
16 # include "ace/SOCK_Dgram.inl"
17 #endif /* __ACE_INLINE__ */
19 #if defined (ACE_HAS_IPV6) && defined (ACE_WIN32)
20 #include /**/ <iphlpapi.h>
23 // This is a workaround for platforms with non-standard
24 // definitions of the ip_mreq structure
25 #if ! defined (IMR_MULTIADDR)
26 #define IMR_MULTIADDR imr_multiaddr
27 #endif /* ! defined (IMR_MULTIADDR) */
29 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
31 ACE_ALLOC_HOOK_DEFINE (ACE_SOCK_Dgram
)
34 ACE_SOCK_Dgram::dump () const
36 #if defined (ACE_HAS_DUMP)
37 ACE_TRACE ("ACE_SOCK_Dgram::dump");
38 #endif /* ACE_HAS_DUMP */
41 // Allows a client to read from a socket without having to provide a
42 // buffer to read. This method determines how much data is in the
43 // socket, allocates a buffer of this size, reads in the data, and
44 // returns the number of bytes read.
47 ACE_SOCK_Dgram::recv (iovec
*io_vec
,
50 const ACE_Time_Value
*timeout
) const
52 ACE_TRACE ("ACE_SOCK_Dgram::recv");
53 #if defined (FIONREAD)
54 if( ACE::handle_read_ready (this->get_handle (), timeout
) != 1 )
59 sockaddr
*saddr
= (sockaddr
*) addr
.get_addr ();
60 int addr_len
= addr
.get_size ();
63 if (ACE_OS::ioctl (this->get_handle (),
69 #if defined (ACE_HAS_ALLOC_HOOKS)
70 ACE_ALLOCATOR_RETURN (io_vec
->iov_base
,
71 static_cast<char*>(ACE_Allocator::instance()->malloc(sizeof(char) * inlen
)),
74 ACE_NEW_RETURN (io_vec
->iov_base
,
77 #endif /* ACE_HAS_ALLOC_HOOKS */
79 ssize_t rcv_len
= ACE_OS::recvfrom (this->get_handle (),
80 (char *) io_vec
->iov_base
,
87 #if defined (ACE_HAS_ALLOC_HOOKS)
88 ACE_Allocator::instance()->free(io_vec
->iov_base
);
90 delete [] (char *)io_vec
->iov_base
;
91 #endif /* ACE_HAS_ALLOC_HOOKS */
96 io_vec
->iov_len
= ACE_Utils::truncate_cast
<u_long
> (rcv_len
);
97 addr
.set_size (addr_len
);
104 ACE_UNUSED_ARG (flags
);
105 ACE_UNUSED_ARG (addr
);
106 ACE_UNUSED_ARG (io_vec
);
107 ACE_UNUSED_ARG (timeout
);
108 ACE_NOTSUP_RETURN (-1);
109 #endif /* FIONREAD */
112 // Here's the shared open function. Note that if we are using the
113 // PF_INET protocol family and the address of LOCAL == the address of
114 // the special variable SAP_ANY then we are going to arbitrarily bind
118 ACE_SOCK_Dgram::shared_open (const ACE_Addr
&local
,
122 ACE_TRACE ("ACE_SOCK_Dgram::shared_open");
124 #if defined (ACE_HAS_IPV6)
125 int setting
= !!ipv6_only
;
126 if (protocol_family
== PF_INET6
&&
127 -1 == ACE_OS::setsockopt (this->get_handle (),
137 ACE_UNUSED_ARG (ipv6_only
);
138 #endif /* defined (ACE_HAS_IPV6) */
140 if (local
== ACE_Addr::sap_any
)
142 if (protocol_family
== PF_INET
143 #if defined (ACE_HAS_IPV6)
144 || protocol_family
== PF_INET6
145 #endif /* ACE_HAS_IPV6 */
148 if (ACE::bind_port (this->get_handle (), INADDR_ANY
, protocol_family
) == -1)
152 else if (ACE_OS::bind (this->get_handle (),
153 reinterpret_cast<sockaddr
*> (local
.get_addr ()),
154 local
.get_size ()) == -1)
160 return error
? -1 : 0;
164 ACE_SOCK_Dgram::open (const ACE_Addr
&local
,
167 ACE_Protocol_Info
*protocolinfo
,
173 if (ACE_SOCK::open (SOCK_DGRAM
,
181 else if (this->shared_open (local
, protocol_family
, ipv6_only
) == -1)
187 // Here's the general-purpose open routine.
190 ACE_SOCK_Dgram::open (const ACE_Addr
&local
,
196 ACE_TRACE ("ACE_SOCK_Dgram::open");
198 if (local
!= ACE_Addr::sap_any
)
199 protocol_family
= local
.get_type ();
200 else if (protocol_family
== PF_UNSPEC
)
202 #if defined (ACE_HAS_IPV6)
203 protocol_family
= ACE::ipv6_enabled () ? PF_INET6
: PF_INET
;
205 protocol_family
= PF_INET
;
206 #endif /* ACE_HAS_IPV6 */
209 if (ACE_SOCK::open (SOCK_DGRAM
, protocol_family
, protocol
, reuse_addr
) == -1)
212 return this->shared_open (local
, protocol_family
, ipv6_only
);
215 // Here's the general-purpose constructor used by a connectionless
216 // datagram ``server''...
218 ACE_SOCK_Dgram::ACE_SOCK_Dgram (const ACE_Addr
&local
,
224 ACE_TRACE ("ACE_SOCK_Dgram::ACE_SOCK_Dgram");
226 if (this->open (local
,
231 ACELIB_ERROR ((LM_ERROR
,
233 ACE_TEXT ("ACE_SOCK_Dgram")));
236 ACE_SOCK_Dgram::ACE_SOCK_Dgram (const ACE_Addr
&local
,
239 ACE_Protocol_Info
*protocolinfo
,
245 ACE_TRACE ("ACE_SOCK_Dgram::ACE_SOCK_Dgram");
246 if (this->open (local
,
254 ACELIB_ERROR ((LM_ERROR
,
256 ACE_TEXT ("ACE_SOCK_Dgram")));
259 #if defined (ACE_HAS_MSG)
260 // Send an iovec of size N to ADDR as a datagram (connectionless
264 ACE_SOCK_Dgram::send (const iovec iov
[],
266 const ACE_Addr
&addr
,
269 ACE_TRACE ("ACE_SOCK_Dgram::send");
272 send_msg
.msg_iov
= (iovec
*) iov
;
273 send_msg
.msg_iovlen
= n
;
274 #if defined (ACE_HAS_SOCKADDR_MSG_NAME)
275 send_msg
.msg_name
= (struct sockaddr
*) addr
.get_addr ();
277 send_msg
.msg_name
= (char *) addr
.get_addr ();
278 #endif /* ACE_HAS_SOCKADDR_MSG_NAME */
279 send_msg
.msg_namelen
= addr
.get_size ();
281 #if defined (ACE_HAS_4_4BSD_SENDMSG_RECVMSG)
282 send_msg
.msg_control
= 0;
283 send_msg
.msg_controllen
= 0;
284 send_msg
.msg_flags
= 0;
285 #elif !defined ACE_LACKS_SENDMSG
286 send_msg
.msg_accrights
= 0;
287 send_msg
.msg_accrightslen
= 0;
288 #endif /* ACE_HAS_4_4BSD_SENDMSG_RECVMSG */
291 send_msg
.msg_control
= 0;
292 send_msg
.msg_controllen
= 0;
295 return ACE_OS::sendmsg (this->get_handle (), &send_msg
, flags
);
298 // Recv an iovec of size N to ADDR as a datagram (connectionless
301 ACE_SOCK_Dgram::recv (iovec iov
[],
305 ACE_INET_Addr
*to_addr
) const
307 ACE_TRACE ("ACE_SOCK_Dgram::recv");
310 #if defined (ACE_HAS_4_4BSD_SENDMSG_RECVMSG) || defined ACE_WIN32
311 #define ACE_USE_MSG_CONTROL
312 union control_buffer
{
313 cmsghdr control_msg_header
;
314 #if defined (IP_RECVDSTADDR) && !defined (ACE_HAS_NONCONST_CMSG_SPACE)
315 u_char padding
[ACE_CMSG_SPACE (sizeof (in_addr
))];
316 #elif defined (IP_PKTINFO) && !defined (ACE_HAS_NONCONST_CMSG_SPACE)
317 u_char padding
[ACE_CMSG_SPACE (sizeof (in_pktinfo
))];
319 #if defined (ACE_HAS_IPV6) && !defined (ACE_HAS_NONCONST_CMSG_SPACE)
320 u_char padding6
[ACE_CMSG_SPACE (sizeof (in6_pktinfo
))];
324 ACE_UNUSED_ARG (to_addr
);
327 recv_msg
.msg_iov
= (iovec
*) iov
;
328 recv_msg
.msg_iovlen
= n
;
329 #if defined (ACE_HAS_SOCKADDR_MSG_NAME)
330 recv_msg
.msg_name
= (struct sockaddr
*) addr
.get_addr ();
332 recv_msg
.msg_name
= (char *) addr
.get_addr ();
333 #endif /* ACE_HAS_SOCKADDR_MSG_NAME */
334 recv_msg
.msg_namelen
= addr
.get_size ();
336 #ifdef ACE_USE_MSG_CONTROL
337 recv_msg
.msg_control
= to_addr
? std::addressof(cbuf
) : nullptr;
338 recv_msg
.msg_controllen
= to_addr
? sizeof (cbuf
) : 0;
339 #elif !defined ACE_LACKS_SENDMSG
340 recv_msg
.msg_accrights
= nullptr;
341 recv_msg
.msg_accrightslen
= 0;
344 ssize_t
const status
= ACE_OS::recvmsg (this->get_handle (), std::addressof(recv_msg
), flags
);
345 addr
.set_size (recv_msg
.msg_namelen
);
346 addr
.set_type (((sockaddr_in
*) addr
.get_addr())->sin_family
);
348 #ifdef ACE_USE_MSG_CONTROL
350 this->get_local_addr (*to_addr
);
351 if (to_addr
->get_type() == AF_INET
) {
352 #if (defined (IP_RECVDSTADDR) || defined (IP_PKTINFO)) && !defined (ACE_HAS_NONCONST_CMSG_SPACE)
353 for (cmsghdr
*ptr
= ACE_CMSG_FIRSTHDR (&recv_msg
); ptr
; ptr
= ACE_CMSG_NXTHDR (&recv_msg
, ptr
)) {
354 #if defined (IP_RECVDSTADDR)
355 if (ptr
->cmsg_level
== IPPROTO_IP
&& ptr
->cmsg_type
== IP_RECVDSTADDR
) {
356 to_addr
->set_address ((const char *) (ACE_CMSG_DATA (ptr
)),
357 sizeof (struct in_addr
),
362 if (ptr
->cmsg_level
== IPPROTO_IP
&& ptr
->cmsg_type
== IP_PKTINFO
) {
363 to_addr
->set_address ((const char *) &(((in_pktinfo
*) (ACE_CMSG_DATA (ptr
)))->ipi_addr
),
364 sizeof (struct in_addr
),
372 #if defined (ACE_HAS_IPV6) && defined (IPV6_PKTINFO) && !defined (ACE_HAS_NONCONST_CMSG_SPACE)
373 else if (to_addr
->get_type() == AF_INET6
) {
374 for (cmsghdr
*ptr
= ACE_CMSG_FIRSTHDR (&recv_msg
); ptr
; ptr
= ACE_CMSG_NXTHDR (&recv_msg
, ptr
)) {
375 if (ptr
->cmsg_level
== IPPROTO_IPV6
&& ptr
->cmsg_type
== IPV6_PKTINFO
) {
376 to_addr
->set_address ((const char *) &(((in6_pktinfo
*)(ACE_CMSG_DATA (ptr
)))->ipi6_addr
),
377 sizeof (struct in6_addr
),
391 #else /* ACE_HAS_MSG */
393 /// Send an iovec of size N to ADDR as a datagram (connectionless
396 ACE_SOCK_Dgram::send (const iovec iov
[],
398 const ACE_Addr
&addr
,
401 ACE_TRACE ("ACE_SOCK_Dgram::send");
406 // Determine the total length of all the buffers in <iov>.
407 for (i
= 0; i
< n
; i
++)
408 #if ! (defined(ACE_LACKS_IOVEC) || defined(ACE_LINUX))
409 // The iov_len is unsigned on Linux and when using the ACE iovec struct. If we go
410 // ahead and try the if, it will emit a warning.
411 if (iov
[i
].iov_len
< 0)
415 length
+= iov
[i
].iov_len
;
419 #if defined (ACE_HAS_ALLOCA)
420 buf
= alloca (length
);
422 # ifdef ACE_HAS_ALLOC_HOOKS
423 ACE_ALLOCATOR_RETURN (buf
, (buf
*)
424 ACE_Allocator::instance ()->malloc (length
), -1);
429 # endif /* ACE_HAS_ALLOC_HOOKS */
430 #endif /* !defined (ACE_HAS_ALLOCA) */
434 for (i
= 0; i
< n
; i
++)
436 ACE_OS::memcpy (ptr
, iov
[i
].iov_base
, iov
[i
].iov_len
);
437 ptr
+= iov
[i
].iov_len
;
440 ssize_t result
= ACE_SOCK_Dgram::send (buf
, length
, addr
, flags
);
441 #if !defined (ACE_HAS_ALLOCA)
442 # ifdef ACE_HAS_ALLOC_HOOKS
443 ACE_Allocator::instance ()->free (buf
);
446 # endif /* ACE_HAS_ALLOC_HOOKS */
447 #endif /* !defined (ACE_HAS_ALLOCA) */
451 // Recv an iovec of size N to ADDR as a datagram (connectionless
455 ACE_SOCK_Dgram::recv (iovec iov
[],
459 ACE_INET_Addr
*to_addr
) const
461 ACE_TRACE ("ACE_SOCK_Dgram::recv");
466 ACE_UNUSED_ARG (to_addr
);
468 for (i
= 0; i
< n
; i
++)
469 #if ! (defined(ACE_LACKS_IOVEC) || defined(ACE_LINUX))
470 // The iov_len is unsigned on Linux and when using the ACE iovec struct. If we go
471 // ahead and try the if, it will emit a warning.
472 if (iov
[i
].iov_len
< 0)
476 length
+= iov
[i
].iov_len
;
480 #if defined (ACE_HAS_ALLOCA)
481 buf
= alloca (length
);
483 # ifdef ACE_HAS_ALLOC_HOOKS
484 ACE_ALLOCATOR_RETURN (buf
, (buf
*)
485 ACE_Allocator::instance ()->malloc (length
), -1);
490 # endif /* ACE_HAS_ALLOC_HOOKS */
491 #endif /* !defined (ACE_HAS_ALLOCA) */
493 length
= ACE_SOCK_Dgram::recv (buf
, length
, addr
, flags
);
500 for (i
= 0; i
< n
&& copyn
> 0; i
++)
502 ACE_OS::memcpy (iov
[i
].iov_base
, ptr
,
503 // iov_len is int on some platforms, size_t on others
504 copyn
> (int) iov
[i
].iov_len
505 ? (size_t) iov
[i
].iov_len
507 ptr
+= iov
[i
].iov_len
;
508 copyn
-= iov
[i
].iov_len
;
512 #if !defined (ACE_HAS_ALLOCA)
513 # ifdef ACE_HAS_ALLOC_HOOKS
514 ACE_Allocator::instance ()->free (buf
);
517 # endif /* ACE_HAS_ALLOC_HOOKS */
518 #endif /* !defined (ACE_HAS_ALLOCA) */
522 #endif /* ACE_HAS_MSG */
525 ACE_SOCK_Dgram::recv (void *buf
,
529 const ACE_Time_Value
*timeout
) const
531 if( ACE::handle_read_ready (this->get_handle (), timeout
) == 1 )
533 // Goes fine, call <recv> to get data
534 return this->recv (buf
, n
, addr
, flags
);
543 ACE_SOCK_Dgram::send (const void *buf
,
545 const ACE_Addr
&addr
,
547 const ACE_Time_Value
*timeout
) const
549 // Check the status of the current socket.
550 if( ACE::handle_write_ready (this->get_handle (), timeout
) == 1 )
552 // Goes fine, call <send> to transmit the data.
553 return this->send (buf
, n
, addr
, flags
);
562 ACE_SOCK_Dgram::set_nic (const ACE_TCHAR
*net_if
,
565 #if defined (IP_MULTICAST_IF) && (IP_MULTICAST_IF != 0)
566 # if defined (ACE_HAS_IPV6)
567 bool ipv6_mif_set
= false;
568 if (addr_family
== AF_INET6
|| addr_family
== AF_UNSPEC
)
571 addr
.set (static_cast<u_short
> (0), ACE_IPV6_ANY
);
573 if (this->make_multicast_ifaddr6 (&send_mreq
,
578 // Only let this attempt to set unknown interface when INET6 is
579 // specifically requested. Otherwise we will just try INET.
580 if (send_mreq
.ipv6mr_interface
!= 0 || addr_family
== AF_INET6
)
582 if (this->ACE_SOCK::set_option
583 (IPPROTO_IPV6
, IPV6_MULTICAST_IF
,
584 &(send_mreq
.ipv6mr_interface
),
585 sizeof send_mreq
.ipv6mr_interface
) == -1)
588 ipv6_mif_set
= send_mreq
.ipv6mr_interface
!= 0;
591 # if defined (ACE_WIN32)
592 // For Win32 net_if is distintly different between INET6 and INET
593 // so it is always either an INET6 if or an INET if.
594 if (!ipv6_mif_set
&& (addr_family
== AF_INET
|| addr_family
== AF_UNSPEC
))
596 if (addr_family
== AF_INET
|| addr_family
== AF_UNSPEC
)
599 ACE_INET_Addr
addr (static_cast<u_short
> (0));
601 if (this->make_multicast_ifaddr (&send_mreq
, addr
, net_if
) == -1)
606 else if (this->ACE_SOCK::set_option (IPPROTO_IP
,
608 &(send_mreq
.imr_interface
),
609 sizeof send_mreq
.imr_interface
) == -1)
615 # else /* ACE_HAS_IPV6 */
616 ACE_UNUSED_ARG (addr_family
);
617 ACE_INET_Addr
addr (static_cast<u_short
> (0));
619 if (this->make_multicast_ifaddr (&send_mreq
,
623 if (this->ACE_SOCK::set_option (IPPROTO_IP
,
625 &(send_mreq
.imr_interface
),
626 sizeof send_mreq
.imr_interface
) == -1)
628 # endif /* !ACE_HAS_IPV6 */
629 #else /* IP_MULTICAST_IF */
630 // Send interface option not supported - ignore it.
631 // (We may have been invoked by ::subscribe, so we have to allow
632 // a non-null interface parameter in this function.)
633 ACE_UNUSED_ARG (net_if
);
634 ACE_UNUSED_ARG (addr_family
);
635 ACELIB_DEBUG ((LM_DEBUG
,
636 ACE_TEXT ("Send interface specification not ")
637 ACE_TEXT ("supported - IGNORED.\n")));
638 #endif /* !IP_MULTICAST_IF */
644 ACE_SOCK_Dgram::make_multicast_ifaddr (ip_mreq
*ret_mreq
,
645 const ACE_INET_Addr
&mcast_addr
,
646 const ACE_TCHAR
*net_if
)
648 ACE_TRACE ("ACE_SOCK_Dgram::make_multicast_ifaddr");
649 ip_mreq lmreq
; // Scratch copy.
652 #if defined (ACE_WIN32)
653 // This port number is not necessary, just convenient
654 ACE_INET_Addr interface_addr
;
655 if (interface_addr
.set (mcast_addr
.get_port_number (), net_if
) == -1)
657 IP_ADAPTER_ADDRESSES tmp_addrs
;
658 // Initial call to determine actual memory size needed
660 if (::GetAdaptersAddresses (AF_INET
, 0, 0, &tmp_addrs
, &bufLen
)
661 != ERROR_BUFFER_OVERFLOW
)
663 return -1; // With output bufferlength 0 this can't be right.
666 // Get required output buffer and retrieve info for real.
668 ACE_NEW_RETURN (buf
, char[bufLen
], -1);
669 PIP_ADAPTER_ADDRESSES pAddrs
= reinterpret_cast<PIP_ADAPTER_ADDRESSES
> (buf
);
670 if (::GetAdaptersAddresses (AF_INET
, 0, 0, pAddrs
, &bufLen
) != NO_ERROR
)
672 delete[] buf
; // clean up
676 interface_addr
= ACE_INET_Addr ();
678 while (pAddrs
&& set_result
== -1)
680 if (ACE_OS::strcmp (ACE_TEXT_ALWAYS_CHAR (net_if
), pAddrs
->AdapterName
) == 0 ||
681 ACE_OS::strcmp (ACE_TEXT_ALWAYS_WCHAR (net_if
), pAddrs
->FriendlyName
) == 0)
683 PIP_ADAPTER_UNICAST_ADDRESS pUnicast
= pAddrs
->FirstUnicastAddress
;
684 LPSOCKADDR sa
= pUnicast
->Address
.lpSockaddr
;
685 if (sa
->sa_family
== AF_INET
)
687 const void *addr
= &(((sockaddr_in
*)sa
)->sin_addr
);
688 set_result
= interface_addr
.set_address ((const char*) addr
, 4, 0);
691 pAddrs
= pAddrs
->Next
;
694 delete[] buf
; // clean up
695 if (set_result
== -1)
701 lmreq
.imr_interface
.s_addr
=
702 ACE_HTONL (interface_addr
.get_ip_address ());
705 ACE_OS::strsncpy (if_address
.ifr_name
, ACE_TEXT_ALWAYS_CHAR (net_if
), (sizeof if_address
.ifr_name
));
706 if (ACE_OS::ioctl (this->get_handle (),
710 // The net_if name failed to be found. It seems that older linux
711 // kernals only support the actual interface name (eg. "eth0"),
712 // not the IP address string of the interface (eg. "192.168.0.1"),
713 // which newer kernals seem to automatically translate.
714 // So assume that we have been given an IP Address and translate
715 // that instead, similar to the above for windows.
716 ACE_INET_Addr interface_addr
;
717 if (interface_addr
.set (mcast_addr
.get_port_number (), net_if
) == -1)
718 return -1; // Still doesn't work, unknown device specified.
719 lmreq
.imr_interface
.s_addr
=
720 ACE_HTONL (interface_addr
.get_ip_address ());
724 sockaddr_in
*socket_address
=
725 reinterpret_cast<sockaddr_in
*> (&if_address
.ifr_addr
);
726 lmreq
.imr_interface
.s_addr
= socket_address
->sin_addr
.s_addr
;
728 #endif /* ACE_WIN32 */
731 lmreq
.imr_interface
.s_addr
= INADDR_ANY
;
733 lmreq
.IMR_MULTIADDR
.s_addr
= ACE_HTONL (mcast_addr
.get_ip_address ());
735 // Set return info, if requested.
742 #if defined (ACE_HAS_IPV6)
743 // XXX: This will not work on any operating systems that do not support
744 // if_nametoindex or that is not Win32 >= Windows XP/Server 2003
746 ACE_SOCK_Dgram::make_multicast_ifaddr6 (ipv6_mreq
*ret_mreq
,
747 const ACE_INET_Addr
&mcast_addr
,
748 const ACE_TCHAR
*net_if
)
750 ACE_TRACE ("ACE_SOCK_Dgram::make_multicast_ifaddr6");
751 ipv6_mreq lmreq
; // Scratch copy.
753 ACE_OS::memset (&lmreq
, 0, sizeof (lmreq
));
755 #if defined (ACE_WIN32) || !defined (ACE_LACKS_IF_NAMETOINDEX)
758 #if defined (ACE_WIN32)
761 ACE_OS::ace_isdigit (net_if
[0]) &&
762 (if_ix
= ACE_OS::atoi (net_if
)) > 0;
764 ULONG bufLen
= 15000; // Initial size as per Microsoft
766 ACE_NEW_RETURN (buf
, char[bufLen
], -1);
768 ULONG iterations
= 0;
769 ULONG
const maxTries
= 3;
770 PIP_ADAPTER_ADDRESSES pAddrs
;
773 pAddrs
= reinterpret_cast<PIP_ADAPTER_ADDRESSES
> (buf
);
774 dwRetVal
= ::GetAdaptersAddresses (AF_INET6
, 0, 0, pAddrs
, &bufLen
);
775 if (dwRetVal
== ERROR_BUFFER_OVERFLOW
)
778 ACE_NEW_RETURN (buf
, char[bufLen
], -1);
785 } while (dwRetVal
== ERROR_BUFFER_OVERFLOW
&& iterations
< maxTries
);
787 if (dwRetVal
!= NO_ERROR
)
796 if ((num_if
&& pAddrs
->Ipv6IfIndex
== static_cast<unsigned int>(if_ix
))
798 (ACE_OS::strcmp (ACE_TEXT_ALWAYS_CHAR (net_if
), pAddrs
->AdapterName
) == 0
799 || ACE_OS::strcmp (ACE_TEXT_ALWAYS_WCHAR (net_if
), pAddrs
->FriendlyName
) == 0)))
801 lmreq
.ipv6mr_interface
= pAddrs
->Ipv6IfIndex
;
805 pAddrs
= pAddrs
->Next
;
808 delete[] buf
; // clean up
810 #else /* ACE_WIN32 */
811 #ifndef ACE_LACKS_IF_NAMETOINDEX
812 lmreq
.ipv6mr_interface
= ACE_OS::if_nametoindex (ACE_TEXT_ALWAYS_CHAR (net_if
));
813 #endif /* ACE_LACKS_IF_NAMETOINDEX */
814 #endif /* ACE_WIN32 */
815 if (lmreq
.ipv6mr_interface
== 0)
821 #else /* ACE_WIN32 || !ACE_LACKS_IF_NAMETOINDEX */
822 ACE_UNUSED_ARG(net_if
);
823 #endif /* ACE_WIN32 || !ACE_LACKS_IF_NAMETOINDEX */
825 // now set the multicast address
826 ACE_OS::memcpy (&lmreq
.ipv6mr_multiaddr
,
827 &((sockaddr_in6
*) mcast_addr
.get_addr ())->sin6_addr
,
830 // Set return info, if requested.
836 #endif /* ACE_HAS_IPV6 */
838 ACE_END_VERSIONED_NAMESPACE_DECL