2 #include "ace/OS_NS_netdb.h"
4 #if !defined (ACE_HAS_INLINED_OSCALLS)
5 # include "ace/OS_NS_netdb.inl"
6 #endif /* ACE_HAS_INLINED_OSCALLS */
8 #if defined (ACE_WIN32) && defined (ACE_HAS_PHARLAP)
9 # include "ace/OS_NS_stdio.h"
12 #include "ace/os_include/net/os_if.h"
13 #include "ace/Global_Macros.h"
14 #include "ace/OS_NS_arpa_inet.h"
15 #include "ace/OS_NS_stdlib.h"
16 #include "ace/OS_NS_stropts.h"
17 #include "ace/OS_NS_sys_socket.h"
18 #include "ace/OS_NS_unistd.h"
20 #if defined (ACE_LINUX) && !defined (ACE_LACKS_NETWORKING)
21 # include "ace/os_include/os_ifaddrs.h"
22 #endif /* ACE_LINUX && !ACE_LACKS_NETWORKING */
24 #ifdef ACE_LACKS_IOCTL
25 #include "ace/OS_NS_devctl.h"
29 # include "ace/os_include/sys/os_sysctl.h"
30 # include <net/route.h>
33 #ifdef ACE_HAS_ALLOC_HOOKS
34 # include "ace/Malloc_Base.h"
37 // Include if_arp so that getmacaddr can use the
40 # include /**/ <net/if_arp.h>
45 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
48 ACE_OS::getmacaddress (struct macaddr_node_t
*node
)
50 ACE_OS_TRACE ("ACE_OS::getmacaddress");
52 #if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
53 # if !defined (ACE_HAS_PHARLAP)
54 /** Define a structure for use with the netbios routine */
58 NAME_BUFFER NameBuff
[30];
65 ACE_OS::memset (&ncb
, 0, sizeof(ncb
));
66 ncb
.ncb_command
= NCBENUM
;
67 ncb
.ncb_buffer
= reinterpret_cast<unsigned char*> (&lenum
);
68 ncb
.ncb_length
= sizeof(lenum
);
70 result
= Netbios (&ncb
);
72 for(int i
= 0; i
< lenum
.length
; i
++)
74 ACE_OS::memset (&ncb
, 0, sizeof(ncb
));
75 ncb
.ncb_command
= NCBRESET
;
76 ncb
.ncb_lana_num
= lenum
.lana
[i
];
78 /** Reset the netbios */
79 result
= Netbios (&ncb
);
81 if (ncb
.ncb_retcode
!= NRC_GOODRET
)
87 ACE_OS::memset (&ncb
, 0, sizeof (ncb
));
88 ACE_OS::strcpy (reinterpret_cast<char*> (ncb
.ncb_callname
), "*");
89 ncb
.ncb_command
= NCBASTAT
;
90 ncb
.ncb_lana_num
= lenum
.lana
[i
];
91 ncb
.ncb_buffer
= reinterpret_cast<unsigned char*> (&adapter
);
92 ncb
.ncb_length
= sizeof (adapter
);
94 result
= Netbios (&ncb
);
98 ACE_OS::memcpy (node
->node
,
99 adapter
.adapt
.adapter_address
,
106 # if defined (ACE_HAS_PHARLAP_RT)
107 DEVHANDLE ip_dev
= (DEVHANDLE
)0;
108 EK_TCPIPCFG
*devp
= 0;
110 ACE_TCHAR dev_name
[16];
112 for (i
= 0; i
< 10; i
++)
115 ACE_OS::snprintf (dev_name
, 16, "ether%d", i
);
116 ip_dev
= EtsTCPGetDeviceHandle (dev_name
);
122 devp
= EtsTCPGetDeviceCfg (ip_dev
);
125 ACE_OS::memcpy (node
->node
,
126 &devp
->EthernetAddress
[0],
130 ACE_UNUSED_ARG (node
);
131 ACE_NOTSUP_RETURN (-1);
132 # endif /* ACE_HAS_PHARLAP_RT */
133 # endif /* ACE_HAS_PHARLAP */
136 /** obtain the local host name */
137 char hostname
[MAXHOSTNAMELEN
];
138 ACE_OS::hostname (hostname
, sizeof (hostname
));
140 /** Get the hostent to use with ioctl */
141 struct hostent
*phost
=
142 ACE_OS::gethostbyname (hostname
);
148 ACE_OS::socket (PF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
150 if (handle
== ACE_INVALID_HANDLE
)
153 char **paddrs
= phost
->h_addr_list
;
157 struct sockaddr_in
*psa
=
158 (struct sockaddr_in
*)&(ar
.arp_pa
);
162 sizeof (struct arpreq
));
164 psa
->sin_family
= AF_INET
;
166 ACE_OS::memcpy (&(psa
->sin_addr
),
168 sizeof (struct in_addr
));
170 if (ACE_OS::ioctl (handle
,
174 ACE_OS::close (handle
);
178 ACE_OS::close (handle
);
180 ACE_OS::memcpy (node
->node
,
186 #elif defined (ACE_LINUX) && !defined (ACE_LACKS_NETWORKING)
188 // It's easiest to know the first MAC-using interface. Use the BSD
189 // getifaddrs function that simplifies access to connected interfaces.
190 struct ifaddrs
*ifap
= 0;
191 struct ifaddrs
*p_if
= 0;
193 if (::getifaddrs (&ifap
) != 0)
196 for (p_if
= ifap
; p_if
!= 0; p_if
= p_if
->ifa_next
)
198 if (p_if
->ifa_addr
== 0)
201 // Check to see if it's up and is not either PPP or loopback
202 if ((p_if
->ifa_flags
& IFF_UP
) == IFF_UP
&&
203 (p_if
->ifa_flags
& (IFF_LOOPBACK
| IFF_POINTOPOINT
)) == 0)
209 ::freeifaddrs (ifap
);
214 ACE_OS::strcpy (ifr
.ifr_name
, p_if
->ifa_name
);
215 ::freeifaddrs (ifap
);
218 ACE_OS::socket (PF_INET
, SOCK_DGRAM
, 0);
220 if (handle
== ACE_INVALID_HANDLE
)
223 # ifdef ACE_LACKS_IOCTL
225 if (ACE_OS::posix_devctl (handle
, SIOCGIFHWADDR
, &ifr
, sizeof ifr
, &info
) < 0)
227 if (ACE_OS::ioctl (handle
/*s*/, SIOCGIFHWADDR
, &ifr
) < 0)
230 ACE_OS::close (handle
);
234 struct sockaddr
* sa
=
235 (struct sockaddr
*) &ifr
.ifr_addr
;
237 ACE_OS::close (handle
);
239 ACE_OS::memcpy (node
->node
,
245 #elif defined (__ANDROID_API__) && defined (ACE_HAS_SIOCGIFCONF) && !defined (ACE_LACKS_NETWORKING)
248 struct ifreq ifr_buf
[32];
252 ACE_OS::socket (AF_INET
, SOCK_DGRAM
, 0);
254 if (handle
== ACE_INVALID_HANDLE
)
260 ifc
.ifc_len
= sizeof(ifr_buf
);
261 ifc
.ifc_req
= &ifr_buf
[0];
263 if (ACE_OS::ioctl (handle
, SIOCGIFCONF
, &ifc
) < 0)
265 ACE_OS::close (handle
);
269 int numif
= ifc
.ifc_len
/ sizeof(struct ifreq
);
271 // find first eligible device
272 struct ifreq
* ifr
= 0;
273 for (int i
=0; i
< numif
;++i
)
278 if (ACE_OS::ioctl (handle
, SIOCGIFFLAGS
, ifr
) < 0)
280 ACE_OS::close (handle
);
284 // Check to see if it's up and is not either PPP or loopback
285 if ((ifr
->ifr_flags
& IFF_UP
) == IFF_UP
&&
286 (ifr
->ifr_flags
& (IFF_LOOPBACK
| IFF_POINTOPOINT
)) == 0)
294 ACE_OS::close (handle
);
299 if (ACE_OS::ioctl (handle
, SIOCGIFHWADDR
, ifr
) < 0)
301 ACE_OS::close (handle
);
305 struct sockaddr
* sa
=
306 (struct sockaddr
*) &ifr
->ifr_hwaddr
;
308 ACE_OS::close (handle
);
310 ACE_OS::memcpy (node
->node
,
316 #elif defined (ACE_HAS_SIOCGIFCONF) && !defined (__ANDROID_API__)
318 const long BUFFERSIZE
= 4000;
319 char buffer
[BUFFERSIZE
];
322 struct ifreq
* ifr
= 0;
325 ACE_OS::socket (AF_INET
, SOCK_DGRAM
, 0);
327 if (handle
== ACE_INVALID_HANDLE
)
332 ifc
.ifc_len
= BUFFERSIZE
;
333 ifc
.ifc_buf
= buffer
;
335 if (ACE_OS::ioctl (handle
, SIOCGIFCONF
, &ifc
) < 0)
337 ACE_OS::close (handle
);
341 for(char* ptr
=buffer
; ptr
< buffer
+ ifc
.ifc_len
; )
343 ifr
= (struct ifreq
*) ptr
;
345 if (ifr
->ifr_addr
.sa_family
== AF_LINK
)
347 if(ACE_OS::strcmp (ifr
->ifr_name
, "en0") == 0)
349 struct sockaddr_dl
* sdl
=
350 (struct sockaddr_dl
*) &ifr
->ifr_addr
;
352 ACE_OS::memcpy (node
->node
,
358 ptr
+= sizeof(ifr
->ifr_name
);
360 if(sizeof(ifr
->ifr_addr
) > ifr
->ifr_addr
.sa_len
)
361 ptr
+= sizeof(ifr
->ifr_addr
);
363 ptr
+= ifr
->ifr_addr
.sa_len
;
366 ACE_OS::close (handle
);
370 #elif defined ACE_VXWORKS
372 int name
[] = {CTL_NET
, AF_ROUTE
, 0, 0, NET_RT_IFLIST
, 0};
373 static const size_t name_elts
= sizeof name
/ sizeof name
[0];
375 size_t result_sz
= 0u;
376 if (sysctl (name
, name_elts
, 0, &result_sz
, 0, 0u) != 0)
379 # ifdef ACE_HAS_ALLOC_HOOKS
381 static_cast<char *> (ACE_Allocator::instance ()->malloc (result_sz
));
382 # define ACE_NETDB_CLEANUP ACE_Allocator::instance ()->free (result)
384 char *const result
= static_cast<char *> (ACE_OS::malloc (result_sz
));
385 # define ACE_NETDB_CLEANUP ACE_OS::free (result)
388 if (sysctl (name
, name_elts
, result
, &result_sz
, 0, 0u) != 0)
394 for (size_t pos
= 0, n
; pos
+ sizeof (if_msghdr
) < result_sz
; pos
+= n
)
396 if_msghdr
*const hdr
= reinterpret_cast<if_msghdr
*> (result
+ pos
);
398 sockaddr_dl
*const addr
=
399 reinterpret_cast<sockaddr_dl
*> (result
+ pos
+ sizeof (if_msghdr
));
401 if (addr
->sdl_alen
>= sizeof node
->node
)
403 ACE_OS::memcpy (node
->node
, LLADDR (addr
), sizeof node
->node
);
408 while (pos
+ n
< result_sz
)
410 ifa_msghdr
*const ifa
=
411 reinterpret_cast<ifa_msghdr
*> (result
+ pos
+ n
);
412 if (ifa
->ifam_type
!= RTM_NEWADDR
)
414 n
+= ifa
->ifam_msglen
;
419 # undef ACE_NETDB_CLEANUP
423 ACE_UNUSED_ARG (node
);
424 ACE_NOTSUP_RETURN (-1);
428 #ifdef ACE_LACKS_GETADDRINFO
430 ACE_OS::getaddrinfo_emulation (const char *name
, addrinfo
**result
)
433 ACE_HOSTENT_DATA buffer
;
435 const hostent
*host
= ACE_OS::gethostbyname_r (name
, &entry
, buffer
, &herr
);
449 if (ACE_OS::inet_aton (name
, (in_addr
*) &buffer
[0]) != 0)
452 entry
.h_length
= sizeof (in_addr
);
453 entry
.h_addr_list
= (char **) (buffer
+ sizeof (in_addr
));
454 entry
.h_addr_list
[0] = buffer
;
455 entry
.h_addr_list
[1] = 0;
466 for (char **addr
= host
->h_addr_list
; *addr
; ++addr
, ++n
) /*empty*/;
468 # ifdef ACE_HAS_ALLOC_HOOKS
469 ACE_Allocator
*const al
= ACE_Allocator::instance ();
470 # define ACE_ALLOC al->
472 # define ACE_ALLOC ACE_OS::
475 ACE_ALLOCATOR_RETURN (*result
,
476 (addrinfo
*) ACE_ALLOC
calloc (n
, sizeof (addrinfo
)),
479 sockaddr_in
*const addr_storage
=
480 (sockaddr_in
*) ACE_ALLOC
calloc (n
, sizeof (sockaddr_in
));
484 ACE_ALLOC
free (*result
);
489 for (size_t i
= 0; i
< n
; ++i
)
491 (*result
)[i
].ai_family
= AF_INET
;
492 (*result
)[i
].ai_addrlen
= sizeof (sockaddr_in
);
493 (*result
)[i
].ai_addr
= (sockaddr
*) addr_storage
+ i
;
494 (*result
)[i
].ai_addr
->sa_family
= AF_INET
;
495 ACE_OS::memcpy (&addr_storage
[i
].sin_addr
, host
->h_addr_list
[i
],
496 (std::min
) (size_t (host
->h_length
), sizeof (in_addr
)));
498 (*result
)[i
].ai_next
= (*result
) + i
+ 1;
505 ACE_OS::freeaddrinfo_emulation (addrinfo
*result
)
507 # ifdef ACE_HAS_ALLOC_HOOKS
508 ACE_Allocator
*const al
= ACE_Allocator::instance ();
509 al
->free (result
->ai_addr
);
512 ACE_OS::free (result
->ai_addr
);
513 ACE_OS::free (result
);
516 #endif /* ACE_LACKS_GETADDRINFO */
518 #ifdef ACE_LACKS_GETNAMEINFO
520 ACE_OS::getnameinfo_emulation (const sockaddr
*saddr
, ACE_SOCKET_LEN saddr_len
,
521 char *host
, ACE_SOCKET_LEN host_len
)
523 if (saddr_len
!= sizeof (sockaddr_in
) || saddr
->sa_family
!= AF_INET
)
524 return EAI_FAMILY
; // IPv6 support requries actual OS-provided getnameinfo
526 const void *addr
= &((const sockaddr_in
*) saddr
)->sin_addr
;
529 ACE_HOSTENT_DATA buf
;
531 ACE_OS::gethostbyaddr_r (static_cast<const char *> (addr
),
532 # ifdef ACE_LACKS_IN_ADDR_T
537 AF_INET
, &hentry
, buf
, &h_error
);
539 if (hp
== 0 || hp
->h_name
== 0)
542 if (ACE_OS::strlen (hp
->h_name
) >= size_t (host_len
))
546 ACE_OS::memcpy (host
, hp
->h_name
, host_len
- 1);
547 host
[host_len
- 1] = '\0';
552 ACE_OS::strcpy (host
, hp
->h_name
);
555 #endif /* ACE_LACKS_GETNAMEINFO */
557 ACE_END_VERSIONED_NAMESPACE_DECL
559 # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) && defined (ACE_LACKS_NETDB_REENTRANT_FUNCTIONS)
560 # include "ace/OS_NS_Thread.h"
561 # include "ace/Object_Manager_Base.h"
563 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
566 ACE_OS::netdb_acquire (void)
568 return ACE_OS::thread_mutex_lock ((ACE_thread_mutex_t
*)
569 ACE_OS_Object_Manager::preallocated_object
[
570 ACE_OS_Object_Manager::ACE_OS_MONITOR_LOCK
]);
574 ACE_OS::netdb_release (void)
576 return ACE_OS::thread_mutex_unlock ((ACE_thread_mutex_t
*)
577 ACE_OS_Object_Manager::preallocated_object
[
578 ACE_OS_Object_Manager::ACE_OS_MONITOR_LOCK
]);
581 ACE_END_VERSIONED_NAMESPACE_DECL
583 # endif /* defined (ACE_LACKS_NETDB_REENTRANT_FUNCTIONS) */