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 #include "ace/os_include/net/os_if.h"
9 #include "ace/Global_Macros.h"
10 #include "ace/OS_NS_arpa_inet.h"
11 #include "ace/OS_NS_stdlib.h"
12 #include "ace/OS_NS_stropts.h"
13 #include "ace/OS_NS_sys_socket.h"
14 #include "ace/OS_NS_unistd.h"
16 #if defined (ACE_LINUX) && !defined (ACE_LACKS_NETWORKING)
17 # include "ace/os_include/os_ifaddrs.h"
18 #endif /* ACE_LINUX && !ACE_LACKS_NETWORKING */
20 #ifdef ACE_LACKS_IOCTL
21 #include "ace/OS_NS_devctl.h"
25 # include "ace/os_include/sys/os_sysctl.h"
26 # include <net/route.h>
29 #ifdef ACE_HAS_ALLOC_HOOKS
30 # include "ace/Malloc_Base.h"
35 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
38 ACE_OS::getmacaddress (struct macaddr_node_t
*node
)
40 ACE_OS_TRACE ("ACE_OS::getmacaddress");
42 #if defined (ACE_WIN32)
43 /** Define a structure for use with the netbios routine */
47 NAME_BUFFER NameBuff
[30];
54 ACE_OS::memset (&ncb
, 0, sizeof(ncb
));
55 ncb
.ncb_command
= NCBENUM
;
56 ncb
.ncb_buffer
= reinterpret_cast<unsigned char*> (&lenum
);
57 ncb
.ncb_length
= sizeof(lenum
);
59 result
= Netbios (&ncb
);
61 for(int i
= 0; i
< lenum
.length
; i
++)
63 ACE_OS::memset (&ncb
, 0, sizeof(ncb
));
64 ncb
.ncb_command
= NCBRESET
;
65 ncb
.ncb_lana_num
= lenum
.lana
[i
];
67 /** Reset the netbios */
68 result
= Netbios (&ncb
);
70 if (ncb
.ncb_retcode
!= NRC_GOODRET
)
76 ACE_OS::memset (&ncb
, 0, sizeof (ncb
));
77 ACE_OS::strcpy (reinterpret_cast<char*> (ncb
.ncb_callname
), "*");
78 ncb
.ncb_command
= NCBASTAT
;
79 ncb
.ncb_lana_num
= lenum
.lana
[i
];
80 ncb
.ncb_buffer
= reinterpret_cast<unsigned char*> (&adapter
);
81 ncb
.ncb_length
= sizeof (adapter
);
83 result
= Netbios (&ncb
);
87 ACE_OS::memcpy (node
->node
,
88 adapter
.adapt
.adapter_address
,
94 #elif defined (ACE_LINUX) && !defined (ACE_LACKS_NETWORKING)
96 // It's easiest to know the first MAC-using interface. Use the BSD
97 // getifaddrs function that simplifies access to connected interfaces.
98 struct ifaddrs
*ifap
= 0;
99 struct ifaddrs
*p_if
= 0;
101 if (::getifaddrs (&ifap
) != 0)
104 for (p_if
= ifap
; p_if
!= 0; p_if
= p_if
->ifa_next
)
106 if (p_if
->ifa_addr
== 0)
109 // Check to see if it's up and is not either PPP or loopback
110 if ((p_if
->ifa_flags
& IFF_UP
) == IFF_UP
&&
111 (p_if
->ifa_flags
& (IFF_LOOPBACK
| IFF_POINTOPOINT
)) == 0)
117 ::freeifaddrs (ifap
);
122 ACE_OS::strcpy (ifr
.ifr_name
, p_if
->ifa_name
);
123 ::freeifaddrs (ifap
);
126 ACE_OS::socket (PF_INET
, SOCK_DGRAM
, 0);
128 if (handle
== ACE_INVALID_HANDLE
)
131 # ifdef ACE_LACKS_IOCTL
133 if (ACE_OS::posix_devctl (handle
, SIOCGIFHWADDR
, &ifr
, sizeof ifr
, &info
) < 0)
135 if (ACE_OS::ioctl (handle
/*s*/, SIOCGIFHWADDR
, &ifr
) < 0)
138 ACE_OS::close (handle
);
142 struct sockaddr
* sa
=
143 (struct sockaddr
*) &ifr
.ifr_addr
;
145 ACE_OS::close (handle
);
147 ACE_OS::memcpy (node
->node
,
153 #elif defined (__ANDROID_API__) && defined (ACE_HAS_SIOCGIFCONF) && !defined (ACE_LACKS_NETWORKING)
156 struct ifreq ifr_buf
[32];
160 ACE_OS::socket (AF_INET
, SOCK_DGRAM
, 0);
162 if (handle
== ACE_INVALID_HANDLE
)
168 ifc
.ifc_len
= sizeof(ifr_buf
);
169 ifc
.ifc_req
= &ifr_buf
[0];
171 if (ACE_OS::ioctl (handle
, SIOCGIFCONF
, &ifc
) < 0)
173 ACE_OS::close (handle
);
177 int numif
= ifc
.ifc_len
/ sizeof(struct ifreq
);
179 // find first eligible device
180 struct ifreq
* ifr
= 0;
181 for (int i
=0; i
< numif
;++i
)
186 if (ACE_OS::ioctl (handle
, SIOCGIFFLAGS
, ifr
) < 0)
188 ACE_OS::close (handle
);
192 // Check to see if it's up and is not either PPP or loopback
193 if ((ifr
->ifr_flags
& IFF_UP
) == IFF_UP
&&
194 (ifr
->ifr_flags
& (IFF_LOOPBACK
| IFF_POINTOPOINT
)) == 0)
202 ACE_OS::close (handle
);
207 if (ACE_OS::ioctl (handle
, SIOCGIFHWADDR
, ifr
) < 0)
209 ACE_OS::close (handle
);
213 struct sockaddr
* sa
=
214 (struct sockaddr
*) &ifr
->ifr_hwaddr
;
216 ACE_OS::close (handle
);
218 ACE_OS::memcpy (node
->node
,
224 #elif defined (ACE_HAS_SIOCGIFCONF) && !defined (__ANDROID_API__)
226 const long BUFFERSIZE
= 4000;
227 char buffer
[BUFFERSIZE
];
230 struct ifreq
* ifr
= 0;
233 ACE_OS::socket (AF_INET
, SOCK_DGRAM
, 0);
235 if (handle
== ACE_INVALID_HANDLE
)
240 ifc
.ifc_len
= BUFFERSIZE
;
241 ifc
.ifc_buf
= buffer
;
243 if (ACE_OS::ioctl (handle
, SIOCGIFCONF
, &ifc
) < 0)
245 ACE_OS::close (handle
);
249 for(char* ptr
=buffer
; ptr
< buffer
+ ifc
.ifc_len
; )
251 ifr
= (struct ifreq
*) ptr
;
253 if (ifr
->ifr_addr
.sa_family
== AF_LINK
)
255 if(ACE_OS::strcmp (ifr
->ifr_name
, "en0") == 0)
257 struct sockaddr_dl
* sdl
=
258 (struct sockaddr_dl
*) &ifr
->ifr_addr
;
260 ACE_OS::memcpy (node
->node
,
266 ptr
+= sizeof(ifr
->ifr_name
);
268 if(sizeof(ifr
->ifr_addr
) > ifr
->ifr_addr
.sa_len
)
269 ptr
+= sizeof(ifr
->ifr_addr
);
271 ptr
+= ifr
->ifr_addr
.sa_len
;
274 ACE_OS::close (handle
);
278 #elif defined ACE_VXWORKS
280 int name
[] = {CTL_NET
, AF_ROUTE
, 0, 0, NET_RT_IFLIST
, 0};
281 static const size_t name_elts
= sizeof name
/ sizeof name
[0];
283 size_t result_sz
= 0u;
284 if (sysctl (name
, name_elts
, 0, &result_sz
, 0, 0u) != 0)
287 # ifdef ACE_HAS_ALLOC_HOOKS
289 static_cast<char *> (ACE_Allocator::instance ()->malloc (result_sz
));
290 # define ACE_NETDB_CLEANUP ACE_Allocator::instance ()->free (result)
292 char *const result
= static_cast<char *> (ACE_OS::malloc (result_sz
));
293 # define ACE_NETDB_CLEANUP ACE_OS::free (result)
296 if (sysctl (name
, name_elts
, result
, &result_sz
, 0, 0u) != 0)
302 for (size_t pos
= 0, n
; pos
+ sizeof (if_msghdr
) < result_sz
; pos
+= n
)
304 if_msghdr
*const hdr
= reinterpret_cast<if_msghdr
*> (result
+ pos
);
306 sockaddr_dl
*const addr
=
307 reinterpret_cast<sockaddr_dl
*> (result
+ pos
+ sizeof (if_msghdr
));
309 if (addr
->sdl_alen
>= sizeof node
->node
)
311 ACE_OS::memcpy (node
->node
, LLADDR (addr
), sizeof node
->node
);
316 while (pos
+ n
< result_sz
)
318 ifa_msghdr
*const ifa
=
319 reinterpret_cast<ifa_msghdr
*> (result
+ pos
+ n
);
320 if (ifa
->ifam_type
!= RTM_NEWADDR
)
322 n
+= ifa
->ifam_msglen
;
327 # undef ACE_NETDB_CLEANUP
331 ACE_UNUSED_ARG (node
);
332 ACE_NOTSUP_RETURN (-1);
336 #ifdef ACE_LACKS_GETADDRINFO
338 ACE_OS::getaddrinfo_emulation (const char *name
, addrinfo
**result
)
341 ACE_HOSTENT_DATA buffer
;
343 const hostent
*host
= ACE_OS::gethostbyname_r (name
, &entry
, buffer
, &herr
);
357 if (ACE_OS::inet_aton (name
, (in_addr
*) &buffer
[0]) != 0)
360 entry
.h_length
= sizeof (in_addr
);
361 entry
.h_addr_list
= (char **) (buffer
+ sizeof (in_addr
));
362 entry
.h_addr_list
[0] = buffer
;
363 entry
.h_addr_list
[1] = 0;
374 for (char **addr
= host
->h_addr_list
; *addr
; ++addr
, ++n
) /*empty*/;
376 # ifdef ACE_HAS_ALLOC_HOOKS
377 ACE_Allocator
*const al
= ACE_Allocator::instance ();
378 # define ACE_ALLOC al->
380 # define ACE_ALLOC ACE_OS::
383 ACE_ALLOCATOR_RETURN (*result
,
384 (addrinfo
*) ACE_ALLOC
calloc (n
, sizeof (addrinfo
)),
387 sockaddr_in
*const addr_storage
=
388 (sockaddr_in
*) ACE_ALLOC
calloc (n
, sizeof (sockaddr_in
));
392 ACE_ALLOC
free (*result
);
397 for (size_t i
= 0; i
< n
; ++i
)
399 (*result
)[i
].ai_family
= AF_INET
;
400 (*result
)[i
].ai_addrlen
= sizeof (sockaddr_in
);
401 (*result
)[i
].ai_addr
= (sockaddr
*) addr_storage
+ i
;
402 (*result
)[i
].ai_addr
->sa_family
= AF_INET
;
403 ACE_OS::memcpy (&addr_storage
[i
].sin_addr
, host
->h_addr_list
[i
],
404 (std::min
) (size_t (host
->h_length
), sizeof (in_addr
)));
406 (*result
)[i
].ai_next
= (*result
) + i
+ 1;
413 ACE_OS::freeaddrinfo_emulation (addrinfo
*result
)
415 # ifdef ACE_HAS_ALLOC_HOOKS
416 ACE_Allocator
*const al
= ACE_Allocator::instance ();
417 al
->free (result
->ai_addr
);
420 ACE_OS::free (result
->ai_addr
);
421 ACE_OS::free (result
);
424 #endif /* ACE_LACKS_GETADDRINFO */
426 #ifdef ACE_LACKS_GETNAMEINFO
428 ACE_OS::getnameinfo_emulation (const sockaddr
*saddr
, ACE_SOCKET_LEN saddr_len
,
429 char *host
, ACE_SOCKET_LEN host_len
)
431 if (saddr_len
!= sizeof (sockaddr_in
) || saddr
->sa_family
!= AF_INET
)
432 return EAI_FAMILY
; // IPv6 support requries actual OS-provided getnameinfo
434 const void *addr
= &((const sockaddr_in
*) saddr
)->sin_addr
;
437 ACE_HOSTENT_DATA buf
;
439 ACE_OS::gethostbyaddr_r (static_cast<const char *> (addr
),
440 # ifdef ACE_LACKS_IN_ADDR_T
445 AF_INET
, &hentry
, buf
, &h_error
);
447 if (hp
== 0 || hp
->h_name
== 0)
450 if (ACE_OS::strlen (hp
->h_name
) >= size_t (host_len
))
454 ACE_OS::memcpy (host
, hp
->h_name
, host_len
- 1);
455 host
[host_len
- 1] = '\0';
460 ACE_OS::strcpy (host
, hp
->h_name
);
463 #endif /* ACE_LACKS_GETNAMEINFO */
465 ACE_END_VERSIONED_NAMESPACE_DECL
467 # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) && defined (ACE_LACKS_NETDB_REENTRANT_FUNCTIONS)
468 # include "ace/OS_NS_Thread.h"
469 # include "ace/Object_Manager_Base.h"
471 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
474 ACE_OS::netdb_acquire ()
476 return ACE_OS::thread_mutex_lock ((ACE_thread_mutex_t
*)
477 ACE_OS_Object_Manager::preallocated_object
[
478 ACE_OS_Object_Manager::ACE_OS_MONITOR_LOCK
]);
482 ACE_OS::netdb_release ()
484 return ACE_OS::thread_mutex_unlock ((ACE_thread_mutex_t
*)
485 ACE_OS_Object_Manager::preallocated_object
[
486 ACE_OS_Object_Manager::ACE_OS_MONITOR_LOCK
]);
489 ACE_END_VERSIONED_NAMESPACE_DECL
491 # endif /* defined (ACE_LACKS_NETDB_REENTRANT_FUNCTIONS) */