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 (),
150 protocol_family
) == -1)
154 else if (ACE_OS::bind (this->get_handle (),
155 reinterpret_cast<sockaddr
*> (local
.get_addr ()),
156 local
.get_size ()) == -1)
162 return error
? -1 : 0;
166 ACE_SOCK_Dgram::open (const ACE_Addr
&local
,
169 ACE_Protocol_Info
*protocolinfo
,
175 if (ACE_SOCK::open (SOCK_DGRAM
,
183 else if (this->shared_open (local
,
191 // Here's the general-purpose open routine.
194 ACE_SOCK_Dgram::open (const ACE_Addr
&local
,
200 ACE_TRACE ("ACE_SOCK_Dgram::open");
202 if (local
!= ACE_Addr::sap_any
)
203 protocol_family
= local
.get_type ();
204 else if (protocol_family
== PF_UNSPEC
)
206 #if defined (ACE_HAS_IPV6)
207 protocol_family
= ACE::ipv6_enabled () ? PF_INET6
: PF_INET
;
209 protocol_family
= PF_INET
;
210 #endif /* ACE_HAS_IPV6 */
213 if (ACE_SOCK::open (SOCK_DGRAM
,
219 return this->shared_open (local
,
224 // Here's the general-purpose constructor used by a connectionless
225 // datagram ``server''...
227 ACE_SOCK_Dgram::ACE_SOCK_Dgram (const ACE_Addr
&local
,
233 ACE_TRACE ("ACE_SOCK_Dgram::ACE_SOCK_Dgram");
235 if (this->open (local
,
240 ACELIB_ERROR ((LM_ERROR
,
242 ACE_TEXT ("ACE_SOCK_Dgram")));
245 ACE_SOCK_Dgram::ACE_SOCK_Dgram (const ACE_Addr
&local
,
248 ACE_Protocol_Info
*protocolinfo
,
254 ACE_TRACE ("ACE_SOCK_Dgram::ACE_SOCK_Dgram");
255 if (this->open (local
,
263 ACELIB_ERROR ((LM_ERROR
,
265 ACE_TEXT ("ACE_SOCK_Dgram")));
268 #if defined (ACE_HAS_MSG)
269 // Send an iovec of size N to ADDR as a datagram (connectionless
273 ACE_SOCK_Dgram::send (const iovec iov
[],
275 const ACE_Addr
&addr
,
278 ACE_TRACE ("ACE_SOCK_Dgram::send");
281 send_msg
.msg_iov
= (iovec
*) iov
;
282 send_msg
.msg_iovlen
= n
;
283 #if defined (ACE_HAS_SOCKADDR_MSG_NAME)
284 send_msg
.msg_name
= (struct sockaddr
*) addr
.get_addr ();
286 send_msg
.msg_name
= (char *) addr
.get_addr ();
287 #endif /* ACE_HAS_SOCKADDR_MSG_NAME */
288 send_msg
.msg_namelen
= addr
.get_size ();
290 #if defined (ACE_HAS_4_4BSD_SENDMSG_RECVMSG)
291 send_msg
.msg_control
= 0;
292 send_msg
.msg_controllen
= 0;
293 send_msg
.msg_flags
= 0;
294 #elif !defined ACE_LACKS_SENDMSG
295 send_msg
.msg_accrights
= 0;
296 send_msg
.msg_accrightslen
= 0;
297 #endif /* ACE_HAS_4_4BSD_SENDMSG_RECVMSG */
300 send_msg
.msg_control
= 0;
301 send_msg
.msg_controllen
= 0;
304 return ACE_OS::sendmsg (this->get_handle (),
309 // Recv an iovec of size N to ADDR as a datagram (connectionless
313 ACE_SOCK_Dgram::recv (iovec iov
[],
317 ACE_INET_Addr
*to_addr
) const
319 ACE_TRACE ("ACE_SOCK_Dgram::recv");
322 #if defined (ACE_HAS_4_4BSD_SENDMSG_RECVMSG) || defined ACE_WIN32
323 #define ACE_USE_MSG_CONTROL
324 union control_buffer
{
325 cmsghdr control_msg_header
;
326 #if defined (IP_RECVDSTADDR)
327 u_char padding
[ACE_CMSG_SPACE (sizeof (in_addr
))];
328 #elif defined (IP_PKTINFO)
329 u_char padding
[ACE_CMSG_SPACE (sizeof (in_pktinfo
))];
331 #if defined (ACE_HAS_IPV6)
332 u_char padding6
[ACE_CMSG_SPACE (sizeof (in6_pktinfo
))];
336 ACE_UNUSED_ARG (to_addr
);
339 recv_msg
.msg_iov
= (iovec
*) iov
;
340 recv_msg
.msg_iovlen
= n
;
341 #if defined (ACE_HAS_SOCKADDR_MSG_NAME)
342 recv_msg
.msg_name
= (struct sockaddr
*) addr
.get_addr ();
344 recv_msg
.msg_name
= (char *) addr
.get_addr ();
345 #endif /* ACE_HAS_SOCKADDR_MSG_NAME */
346 recv_msg
.msg_namelen
= addr
.get_size ();
348 #ifdef ACE_USE_MSG_CONTROL
349 recv_msg
.msg_control
= to_addr
? &cbuf
: 0;
350 recv_msg
.msg_controllen
= to_addr
? sizeof (cbuf
) : 0;
351 #elif !defined ACE_LACKS_SENDMSG
352 recv_msg
.msg_accrights
= 0;
353 recv_msg
.msg_accrightslen
= 0;
356 ssize_t status
= ACE_OS::recvmsg (this->get_handle (),
359 addr
.set_size (recv_msg
.msg_namelen
);
360 addr
.set_type (((sockaddr_in
*) addr
.get_addr())->sin_family
);
362 #ifdef ACE_USE_MSG_CONTROL
364 this->get_local_addr (*to_addr
);
365 if (to_addr
->get_type() == AF_INET
) {
366 #if defined (IP_RECVDSTADDR) || defined (IP_PKTINFO)
367 for (cmsghdr
*ptr
= ACE_CMSG_FIRSTHDR (&recv_msg
); ptr
; ptr
= ACE_CMSG_NXTHDR (&recv_msg
, ptr
)) {
368 #if defined (IP_RECVDSTADDR)
369 if (ptr
->cmsg_level
== IPPROTO_IP
&& ptr
->cmsg_type
== IP_RECVDSTADDR
) {
370 to_addr
->set_address ((const char *) (ACE_CMSG_DATA (ptr
)),
371 sizeof (struct in_addr
),
376 if (ptr
->cmsg_level
== IPPROTO_IP
&& ptr
->cmsg_type
== IP_PKTINFO
) {
377 to_addr
->set_address ((const char *) &(((in_pktinfo
*) (ACE_CMSG_DATA (ptr
)))->ipi_addr
),
378 sizeof (struct in_addr
),
386 #if defined (ACE_HAS_IPV6) && defined (IPV6_PKTINFO)
387 else if (to_addr
->get_type() == AF_INET6
) {
388 for (cmsghdr
*ptr
= ACE_CMSG_FIRSTHDR (&recv_msg
); ptr
; ptr
= ACE_CMSG_NXTHDR (&recv_msg
, ptr
)) {
389 if (ptr
->cmsg_level
== IPPROTO_IPV6
&& ptr
->cmsg_type
== IPV6_PKTINFO
) {
390 to_addr
->set_address ((const char *) &(((in6_pktinfo
*)(ACE_CMSG_DATA (ptr
)))->ipi6_addr
),
391 sizeof (struct in6_addr
),
405 #else /* ACE_HAS_MSG */
407 // Send an iovec of size N to ADDR as a datagram (connectionless
410 ACE_SOCK_Dgram::send (const iovec iov
[],
412 const ACE_Addr
&addr
,
415 ACE_TRACE ("ACE_SOCK_Dgram::send");
420 // Determine the total length of all the buffers in <iov>.
421 for (i
= 0; i
< n
; i
++)
422 #if ! (defined(ACE_LACKS_IOVEC) || defined(ACE_LINUX))
423 // The iov_len is unsigned on Linux and when using the ACE iovec struct. If we go
424 // ahead and try the if, it will emit a warning.
425 if (iov
[i
].iov_len
< 0)
429 length
+= iov
[i
].iov_len
;
433 #if defined (ACE_HAS_ALLOCA)
434 buf
= alloca (length
);
436 # ifdef ACE_HAS_ALLOC_HOOKS
437 ACE_ALLOCATOR_RETURN (buf
, (buf
*)
438 ACE_Allocator::instance ()->malloc (length
), -1);
443 # endif /* ACE_HAS_ALLOC_HOOKS */
444 #endif /* !defined (ACE_HAS_ALLOCA) */
448 for (i
= 0; i
< n
; i
++)
450 ACE_OS::memcpy (ptr
, iov
[i
].iov_base
, iov
[i
].iov_len
);
451 ptr
+= iov
[i
].iov_len
;
454 ssize_t result
= ACE_SOCK_Dgram::send (buf
, length
, addr
, flags
);
455 #if !defined (ACE_HAS_ALLOCA)
456 # ifdef ACE_HAS_ALLOC_HOOKS
457 ACE_Allocator::instance ()->free (buf
);
460 # endif /* ACE_HAS_ALLOC_HOOKS */
461 #endif /* !defined (ACE_HAS_ALLOCA) */
465 // Recv an iovec of size N to ADDR as a datagram (connectionless
469 ACE_SOCK_Dgram::recv (iovec iov
[],
473 ACE_INET_Addr
*to_addr
) const
475 ACE_TRACE ("ACE_SOCK_Dgram::recv");
480 ACE_UNUSED_ARG (to_addr
);
482 for (i
= 0; i
< n
; i
++)
483 #if ! (defined(ACE_LACKS_IOVEC) || defined(ACE_LINUX))
484 // The iov_len is unsigned on Linux and when using the ACE iovec struct. If we go
485 // ahead and try the if, it will emit a warning.
486 if (iov
[i
].iov_len
< 0)
490 length
+= iov
[i
].iov_len
;
494 #if defined (ACE_HAS_ALLOCA)
495 buf
= alloca (length
);
497 # ifdef ACE_HAS_ALLOC_HOOKS
498 ACE_ALLOCATOR_RETURN (buf
, (buf
*)
499 ACE_Allocator::instance ()->malloc (length
), -1);
504 # endif /* ACE_HAS_ALLOC_HOOKS */
505 #endif /* !defined (ACE_HAS_ALLOCA) */
507 length
= ACE_SOCK_Dgram::recv (buf
, length
, addr
, flags
);
518 ACE_OS::memcpy (iov
[i
].iov_base
, ptr
,
519 // iov_len is int on some platforms, size_t on others
520 copyn
> (int) iov
[i
].iov_len
521 ? (size_t) iov
[i
].iov_len
523 ptr
+= iov
[i
].iov_len
;
524 copyn
-= iov
[i
].iov_len
;
528 #if !defined (ACE_HAS_ALLOCA)
529 # ifdef ACE_HAS_ALLOC_HOOKS
530 ACE_Allocator::instance ()->free (buf
);
533 # endif /* ACE_HAS_ALLOC_HOOKS */
534 #endif /* !defined (ACE_HAS_ALLOCA) */
538 #endif /* ACE_HAS_MSG */
541 ACE_SOCK_Dgram::recv (void *buf
,
545 const ACE_Time_Value
*timeout
) const
547 if( ACE::handle_read_ready (this->get_handle (), timeout
) == 1 )
549 // Goes fine, call <recv> to get data
550 return this->recv (buf
, n
, addr
, flags
);
559 ACE_SOCK_Dgram::send (const void *buf
,
561 const ACE_Addr
&addr
,
563 const ACE_Time_Value
*timeout
) const
565 // Check the status of the current socket.
566 if( ACE::handle_write_ready (this->get_handle (), timeout
) == 1 )
568 // Goes fine, call <send> to transmit the data.
569 return this->send (buf
, n
, addr
, flags
);
578 ACE_SOCK_Dgram::set_nic (const ACE_TCHAR
*net_if
,
581 #if defined (IP_MULTICAST_IF) && (IP_MULTICAST_IF != 0)
582 # if defined (ACE_HAS_IPV6)
583 bool ipv6_mif_set
= false;
584 if (addr_family
== AF_INET6
|| addr_family
== AF_UNSPEC
)
587 addr
.set (static_cast<u_short
> (0), ACE_IPV6_ANY
);
589 if (this->make_multicast_ifaddr6 (&send_mreq
,
594 // Only let this attempt to set unknown interface when INET6 is
595 // specifically requested. Otherwise we will just try INET.
596 if (send_mreq
.ipv6mr_interface
!= 0 || addr_family
== AF_INET6
)
598 if (this->ACE_SOCK::set_option
599 (IPPROTO_IPV6
, IPV6_MULTICAST_IF
,
600 &(send_mreq
.ipv6mr_interface
),
601 sizeof send_mreq
.ipv6mr_interface
) == -1)
604 ipv6_mif_set
= send_mreq
.ipv6mr_interface
!= 0;
607 # if defined (ACE_WIN32)
608 // For Win32 net_if is distintly different between INET6 and INET
609 // so it is always either an INET6 if or an INET if.
610 if (!ipv6_mif_set
&& (addr_family
== AF_INET
|| addr_family
== AF_UNSPEC
))
612 if (addr_family
== AF_INET
|| addr_family
== AF_UNSPEC
)
615 ACE_INET_Addr
addr (static_cast<u_short
> (0));
617 if (this->make_multicast_ifaddr (&send_mreq
,
624 else if (this->ACE_SOCK::set_option (IPPROTO_IP
,
626 &(send_mreq
.imr_interface
),
627 sizeof send_mreq
.imr_interface
) == -1)
633 # else /* ACE_HAS_IPV6 */
634 ACE_UNUSED_ARG (addr_family
);
635 ACE_INET_Addr
addr (static_cast<u_short
> (0));
637 if (this->make_multicast_ifaddr (&send_mreq
,
641 if (this->ACE_SOCK::set_option (IPPROTO_IP
,
643 &(send_mreq
.imr_interface
),
644 sizeof send_mreq
.imr_interface
) == -1)
646 # endif /* !ACE_HAS_IPV6 */
647 #else /* IP_MULTICAST_IF */
648 // Send interface option not supported - ignore it.
649 // (We may have been invoked by ::subscribe, so we have to allow
650 // a non-null interface parameter in this function.)
651 ACE_UNUSED_ARG (net_if
);
652 ACE_UNUSED_ARG (addr_family
);
653 ACELIB_DEBUG ((LM_DEBUG
,
654 ACE_TEXT ("Send interface specification not ")
655 ACE_TEXT ("supported - IGNORED.\n")));
656 #endif /* !IP_MULTICAST_IF */
662 ACE_SOCK_Dgram::make_multicast_ifaddr (ip_mreq
*ret_mreq
,
663 const ACE_INET_Addr
&mcast_addr
,
664 const ACE_TCHAR
*net_if
)
666 ACE_TRACE ("ACE_SOCK_Dgram::make_multicast_ifaddr");
667 ip_mreq lmreq
; // Scratch copy.
670 #if defined (ACE_WIN32)
671 // This port number is not necessary, just convenient
672 ACE_INET_Addr interface_addr
;
673 if (interface_addr
.set (mcast_addr
.get_port_number (), net_if
) == -1)
675 IP_ADAPTER_ADDRESSES tmp_addrs
;
676 // Initial call to determine actual memory size needed
678 if (::GetAdaptersAddresses (AF_INET
, 0, 0, &tmp_addrs
, &bufLen
)
679 != ERROR_BUFFER_OVERFLOW
)
681 return -1; // With output bufferlength 0 this can't be right.
684 // Get required output buffer and retrieve info for real.
686 ACE_NEW_RETURN (buf
, char[bufLen
], -1);
687 PIP_ADAPTER_ADDRESSES pAddrs
= reinterpret_cast<PIP_ADAPTER_ADDRESSES
> (buf
);
688 if (::GetAdaptersAddresses (AF_INET
, 0, 0, pAddrs
, &bufLen
) != NO_ERROR
)
690 delete[] buf
; // clean up
694 interface_addr
= ACE_INET_Addr ();
696 while (pAddrs
&& set_result
== -1)
698 if (ACE_OS::strcmp (ACE_TEXT_ALWAYS_CHAR (net_if
), pAddrs
->AdapterName
) == 0 ||
699 ACE_OS::strcmp (ACE_TEXT_ALWAYS_WCHAR (net_if
), pAddrs
->FriendlyName
) == 0)
701 PIP_ADAPTER_UNICAST_ADDRESS pUnicast
= pAddrs
->FirstUnicastAddress
;
702 LPSOCKADDR sa
= pUnicast
->Address
.lpSockaddr
;
703 if (sa
->sa_family
== AF_INET
)
705 const void *addr
= &(((sockaddr_in
*)sa
)->sin_addr
);
706 set_result
= interface_addr
.set_address ((const char*) addr
, 4, 0);
709 pAddrs
= pAddrs
->Next
;
712 delete[] buf
; // clean up
713 if (set_result
== -1)
719 lmreq
.imr_interface
.s_addr
=
720 ACE_HTONL (interface_addr
.get_ip_address ());
723 ACE_OS::strsncpy (if_address
.ifr_name
, ACE_TEXT_ALWAYS_CHAR (net_if
), (sizeof if_address
.ifr_name
));
724 if (ACE_OS::ioctl (this->get_handle (),
728 // The net_if name failed to be found. It seems that older linux
729 // kernals only support the actual interface name (eg. "eth0"),
730 // not the IP address string of the interface (eg. "192.168.0.1"),
731 // which newer kernals seem to automatically translate.
732 // So assume that we have been given an IP Address and translate
733 // that instead, similar to the above for windows.
734 ACE_INET_Addr interface_addr
;
735 if (interface_addr
.set (mcast_addr
.get_port_number (), net_if
) == -1)
736 return -1; // Still doesn't work, unknown device specified.
737 lmreq
.imr_interface
.s_addr
=
738 ACE_HTONL (interface_addr
.get_ip_address ());
742 sockaddr_in
*socket_address
=
743 reinterpret_cast<sockaddr_in
*> (&if_address
.ifr_addr
);
744 lmreq
.imr_interface
.s_addr
= socket_address
->sin_addr
.s_addr
;
746 #endif /* ACE_WIN32 */
749 lmreq
.imr_interface
.s_addr
= INADDR_ANY
;
751 lmreq
.IMR_MULTIADDR
.s_addr
= ACE_HTONL (mcast_addr
.get_ip_address ());
753 // Set return info, if requested.
760 #if defined (ACE_HAS_IPV6)
761 // XXX: This will not work on any operating systems that do not support
762 // if_nametoindex or that is not Win32 >= Windows XP/Server 2003
764 ACE_SOCK_Dgram::make_multicast_ifaddr6 (ipv6_mreq
*ret_mreq
,
765 const ACE_INET_Addr
&mcast_addr
,
766 const ACE_TCHAR
*net_if
)
768 ACE_TRACE ("ACE_SOCK_Dgram::make_multicast_ifaddr6");
769 ipv6_mreq lmreq
; // Scratch copy.
771 ACE_OS::memset (&lmreq
,
775 #if defined (ACE_WIN32) || !defined (ACE_LACKS_IF_NAMETOINDEX)
778 #if defined (ACE_WIN32)
781 ACE_OS::ace_isdigit (net_if
[0]) &&
782 (if_ix
= ACE_OS::atoi (net_if
)) > 0;
784 ULONG bufLen
= 15000; // Initial size as per Microsoft
786 ACE_NEW_RETURN (buf
, char[bufLen
], -1);
788 ULONG iterations
= 0;
789 ULONG
const maxTries
= 3;
790 PIP_ADAPTER_ADDRESSES pAddrs
;
793 pAddrs
= reinterpret_cast<PIP_ADAPTER_ADDRESSES
> (buf
);
794 dwRetVal
= ::GetAdaptersAddresses (AF_INET6
, 0, 0, pAddrs
, &bufLen
);
795 if (dwRetVal
== ERROR_BUFFER_OVERFLOW
)
798 ACE_NEW_RETURN (buf
, char[bufLen
], -1);
805 } while (dwRetVal
== ERROR_BUFFER_OVERFLOW
&& iterations
< maxTries
);
807 if (dwRetVal
!= NO_ERROR
)
816 if ((num_if
&& pAddrs
->Ipv6IfIndex
== static_cast<unsigned int>(if_ix
))
818 (ACE_OS::strcmp (ACE_TEXT_ALWAYS_CHAR (net_if
), pAddrs
->AdapterName
) == 0
819 || ACE_OS::strcmp (ACE_TEXT_ALWAYS_WCHAR (net_if
), pAddrs
->FriendlyName
) == 0)))
821 lmreq
.ipv6mr_interface
= pAddrs
->Ipv6IfIndex
;
825 pAddrs
= pAddrs
->Next
;
828 delete[] buf
; // clean up
830 #else /* ACE_WIN32 */
831 #ifndef ACE_LACKS_IF_NAMETOINDEX
832 lmreq
.ipv6mr_interface
= ACE_OS::if_nametoindex (ACE_TEXT_ALWAYS_CHAR (net_if
));
833 #endif /* ACE_LACKS_IF_NAMETOINDEX */
834 #endif /* ACE_WIN32 */
835 if (lmreq
.ipv6mr_interface
== 0)
841 #else /* ACE_WIN32 || !ACE_LACKS_IF_NAMETOINDEX */
842 ACE_UNUSED_ARG(net_if
);
843 #endif /* ACE_WIN32 || !ACE_LACKS_IF_NAMETOINDEX */
845 // now set the multicast address
846 ACE_OS::memcpy (&lmreq
.ipv6mr_multiaddr
,
847 &((sockaddr_in6
*) mcast_addr
.get_addr ())->sin6_addr
,
850 // Set return info, if requested.
856 #endif /* ACE_HAS_IPV6 */
858 ACE_END_VERSIONED_NAMESPACE_DECL