OS_NS_netdb.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 // $Id: OS_NS_netdb.cpp 80826 2008-03-04 14:51:23Z wotte $
00003 
00004 #include "ace/OS_NS_netdb.h"
00005 
00006 ACE_RCSID(ace, OS_NS_netdb, "$Id: OS_NS_netdb.cpp 80826 2008-03-04 14:51:23Z wotte $")
00007 
00008 #if !defined (ACE_HAS_INLINED_OSCALLS)
00009 # include "ace/OS_NS_netdb.inl"
00010 #endif /* ACE_HAS_INLINED_OSCALLS */
00011 
00012 #include "ace/os_include/net/os_if.h"
00013 #include "ace/OS_NS_unistd.h"
00014 #if defined (ACE_WIN32) && defined (ACE_HAS_PHARLAP)
00015 #include "ace/OS_NS_stdio.h"
00016 #endif
00017 #include "ace/OS_NS_stropts.h"
00018 #include "ace/OS_NS_sys_socket.h"
00019 
00020 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00021 
00022 #if defined (ACE_VXWORKS) && defined (ACE_LACKS_GETHOSTBYADDR)
00023 
00024 struct hostent *
00025 ACE_OS::gethostbyaddr (const char *addr, int length, int type)
00026 {
00027   ACE_OS_TRACE ("ACE_OS::gethostbyaddr");
00028 
00029   if (length != 4 || type != AF_INET)
00030     {
00031       errno = EINVAL;
00032       return 0;
00033     }
00034 
00035   // not thread safe!
00036   static hostent ret;
00037   static char name [MAXNAMELEN + 1];
00038   static char *hostaddr[2];
00039   static char *aliases[1];
00040 
00041   if (::hostGetByAddr (*(int *) addr, name) != 0)
00042     {
00043       // errno will have been set to S_hostLib_UNKNOWN_HOST.
00044       return 0;
00045     }
00046 
00047   // Might not be official: just echo input arg.
00048   hostaddr[0] = (char *) addr;
00049   hostaddr[1] = 0;
00050   aliases[0] = 0;
00051 
00052   ret.h_name = name;
00053   ret.h_addrtype = AF_INET;
00054   ret.h_length = 4;  // VxWorks 5.2/3 doesn't define IP_ADDR_LEN;
00055   ret.h_addr_list = hostaddr;
00056   ret.h_aliases = aliases;
00057 
00058   return &ret;
00059 }
00060 
00061 #endif /* ACE_VXWORKS && ACE_LACKS_GETHOSTBYADDR */
00062 
00063 #if defined (ACE_VXWORKS) && defined (ACE_LACKS_GETHOSTBYADDR)
00064 
00065 struct hostent *
00066 ACE_OS::gethostbyaddr_r (const char *addr, int length, int type,
00067                          hostent *result, ACE_HOSTENT_DATA buffer,
00068                          int *h_errnop)
00069 {
00070   ACE_OS_TRACE ("ACE_OS::gethostbyaddr_r");
00071   if (length != 4 || type != AF_INET)
00072     {
00073       errno = EINVAL;
00074       return 0;
00075     }
00076 
00077   if (ACE_OS::netdb_acquire ())
00078     return 0;
00079   else
00080     {
00081       // buffer layout:
00082       // buffer[0-3]: h_addr_list[0], the first (and only) addr.
00083       // buffer[4-7]: h_addr_list[1], the null terminator for the h_addr_list.
00084       // buffer[8]: the name of the host, null terminated.
00085 
00086       // Call ::hostGetByAddr (), which puts the (one) hostname into
00087       // buffer.
00088       if (::hostGetByAddr (*(int *) addr, &buffer[8]) == 0)
00089         {
00090           // Store the return values in result.
00091           result->h_name = &buffer[8];  // null-terminated host name
00092           result->h_addrtype = AF_INET;
00093           result->h_length = 4;  // VxWorks 5.2/3 doesn't define IP_ADDR_LEN.
00094 
00095           result->h_addr_list = (char **) buffer;
00096           // Might not be official: just echo input arg.
00097           result->h_addr_list[0] = (char *) addr;
00098           // Null-terminate the list of addresses.
00099           result->h_addr_list[1] = 0;
00100           // And no aliases, so null-terminate h_aliases.
00101           result->h_aliases = &result->h_addr_list[1];
00102         }
00103       else
00104         {
00105           // errno will have been set to S_hostLib_UNKNOWN_HOST.
00106           result = 0;
00107         }
00108     }
00109 
00110   ACE_OS::netdb_release ();
00111   *h_errnop = errno;
00112   return result;
00113 }
00114 
00115 #endif /* ACE_VXWORKS && ACE_LACKS_GETHOSTBYADDR */
00116 
00117 #if defined (ACE_VXWORKS) && defined (ACE_LACKS_GETHOSTBYNAME)
00118 
00119 struct hostent *
00120 ACE_OS::gethostbyname (const char *name)
00121 {
00122   ACE_OS_TRACE ("ACE_OS::gethostbyname");
00123 
00124   // not thread safe!
00125   static hostent ret;
00126   static int first_addr;
00127   static char *hostaddr[2];
00128   static char *aliases[1];
00129 
00130   if (0 == name || '\0' == name[0])
00131     return 0;
00132 
00133   ACE_OSCALL (::hostGetByName (const_cast <char *> (name)), int, -1, first_addr);
00134   if (first_addr == -1)
00135     return 0;
00136 
00137   hostaddr[0] = (char *) &first_addr;
00138   hostaddr[1] = 0;
00139   aliases[0] = 0;
00140 
00141   // Might not be official: just echo input arg.
00142   ret.h_name = (char *) name;
00143   ret.h_addrtype = AF_INET;
00144   ret.h_length = 4;  // VxWorks 5.2/3 doesn't define IP_ADDR_LEN;
00145   ret.h_addr_list = hostaddr;
00146   ret.h_aliases = aliases;
00147 
00148   return &ret;
00149 }
00150 
00151 #endif /* ACE_VXWORKS && ACE_LACKS_GETHOSTBYNAME */
00152 
00153 #if defined (ACE_VXWORKS) && defined (ACE_LACKS_GETHOSTBYNAME)
00154 
00155 struct hostent *
00156 ACE_OS::gethostbyname_r (const char *name, hostent *result,
00157                          ACE_HOSTENT_DATA buffer,
00158                          int *h_errnop)
00159 {
00160   ACE_OS_TRACE ("ACE_OS::gethostbyname_r");
00161 
00162   if (0 == name || '\0' == name[0])
00163     return 0;
00164 
00165   if (ACE_OS::netdb_acquire ())
00166     return 0;
00167   else
00168     {
00169       int addr;
00170       ACE_OSCALL (::hostGetByName (const_cast <char *> (name)), int, -1, addr);
00171 
00172       if (addr == -1)
00173         {
00174           // errno will have been set to S_hostLib_UNKNOWN_HOST
00175           result = 0;
00176         }
00177       else
00178         {
00179           // Might not be official: just echo input arg.
00180           result->h_name = (char *) name;
00181           result->h_addrtype = AF_INET;
00182           result->h_length = 4;  // VxWorks 5.2/3 doesn't define IP_ADDR_LEN;
00183 
00184           // buffer layout:
00185           // buffer[0-3]: h_addr_list[0], pointer to the addr.
00186           // buffer[4-7]: h_addr_list[1], null terminator for the h_addr_list.
00187           // buffer[8-11]: the first (and only) addr.
00188 
00189           // Store the address list in buffer.
00190           result->h_addr_list = (char **) buffer;
00191           // Store the actual address _after_ the address list.
00192           result->h_addr_list[0] = (char *) &result->h_addr_list[2];
00193           result->h_addr_list[2] = (char *) addr;
00194           // Null-terminate the list of addresses.
00195           result->h_addr_list[1] = 0;
00196           // And no aliases, so null-terminate h_aliases.
00197           result->h_aliases = &result->h_addr_list[1];
00198         }
00199     }
00200 
00201   ACE_OS::netdb_release ();
00202   *h_errnop = errno;
00203   return result;
00204 }
00205 
00206 #endif /* ACE_VXWORKS && ACE_LACKS_GETHOSTBYNAME*/
00207 
00208 ACE_END_VERSIONED_NAMESPACE_DECL
00209 
00210 // Include if_arp so that getmacaddr can use the
00211 // arp structure.
00212 #if defined (sun)
00213 # include /**/ <net/if_arp.h>
00214 #endif
00215 
00216 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00217 
00218 int
00219 ACE_OS::getmacaddress (struct macaddr_node_t *node)
00220 {
00221   ACE_OS_TRACE ("ACE_OS::getmacaddress");
00222 
00223 #if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
00224 # if !defined (ACE_HAS_PHARLAP)
00225     /** Define a structure for use with the netbios routine */
00226     struct ADAPTERSTAT
00227     {
00228       ADAPTER_STATUS adapt;
00229       NAME_BUFFER    NameBuff [30];
00230     };
00231 
00232     NCB         ncb;
00233     LANA_ENUM   lenum;
00234     unsigned char result;
00235 
00236     ACE_OS::memset (&ncb, 0, sizeof(ncb));
00237     ncb.ncb_command = NCBENUM;
00238     ncb.ncb_buffer  = reinterpret_cast<unsigned char*> (&lenum);
00239     ncb.ncb_length  = sizeof(lenum);
00240 
00241     result = Netbios (&ncb);
00242 
00243     for(int i = 0; i < lenum.length; i++)
00244       {
00245         ACE_OS::memset (&ncb, 0, sizeof(ncb));
00246         ncb.ncb_command  = NCBRESET;
00247         ncb.ncb_lana_num = lenum.lana [i];
00248 
00249         /** Reset the netbios */
00250         result = Netbios (&ncb);
00251 
00252         if (ncb.ncb_retcode != NRC_GOODRET)
00253         {
00254           return -1;
00255         }
00256 
00257         ADAPTERSTAT adapter;
00258         ACE_OS::memset (&ncb, 0, sizeof (ncb));
00259         ACE_OS::strcpy (reinterpret_cast<char*> (ncb.ncb_callname), "*");
00260         ncb.ncb_command     = NCBASTAT;
00261         ncb.ncb_lana_num    = lenum.lana[i];
00262         ncb.ncb_buffer      = reinterpret_cast<unsigned char*> (&adapter);
00263         ncb.ncb_length      = sizeof (adapter);
00264 
00265         result = Netbios (&ncb);
00266 
00267         if (result == 0)
00268         {
00269           ACE_OS::memcpy (node->node,
00270               adapter.adapt.adapter_address,
00271               6);
00272           return 0;
00273         }
00274       }
00275     return 0;
00276 # else
00277 #   if defined (ACE_HAS_PHARLAP_RT)
00278       DEVHANDLE ip_dev = (DEVHANDLE)0;
00279       EK_TCPIPCFG *devp;
00280       size_t i;
00281       ACE_TCHAR dev_name[16];
00282 
00283       for (i = 0; i < 10; i++)
00284         {
00285           // Ethernet.
00286           ACE_OS::sprintf (dev_name,
00287                            "ether%d",
00288                            i);
00289           ip_dev = EtsTCPGetDeviceHandle (dev_name);
00290           if (ip_dev != 0)
00291             break;
00292         }
00293       if (ip_dev == 0)
00294         return -1;
00295       devp = EtsTCPGetDeviceCfg (ip_dev);
00296       if (devp == 0)
00297         return -1;
00298       ACE_OS::memcpy (node->node,
00299             &devp->EthernetAddress[0],
00300             6);
00301       return 0;
00302 #   else
00303       ACE_UNUSED_ARG (node);
00304       ACE_NOTSUP_RETURN (-1);
00305 #   endif /* ACE_HAS_PHARLAP_RT */
00306 # endif /* ACE_HAS_PHARLAP */
00307 #elif defined (sun)
00308 
00309   /** obtain the local host name */
00310   char hostname [MAXHOSTNAMELEN];
00311   ACE_OS::hostname (hostname, sizeof (hostname));
00312 
00313   /** Get the hostent to use with ioctl */
00314   struct hostent *phost =
00315     ACE_OS::gethostbyname (hostname);
00316 
00317   if (phost == 0)
00318     return -1;
00319 
00320   ACE_HANDLE handle =
00321     ACE_OS::socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
00322 
00323   if (handle == ACE_INVALID_HANDLE)
00324     return -1;
00325 
00326   char **paddrs = phost->h_addr_list;
00327 
00328   struct arpreq ar;
00329 
00330   struct sockaddr_in *psa =
00331     (struct sockaddr_in *)&(ar.arp_pa);
00332 
00333   ACE_OS::memset (&ar,
00334                   0,
00335                   sizeof (struct arpreq));
00336 
00337   psa->sin_family = AF_INET;
00338 
00339   ACE_OS::memcpy (&(psa->sin_addr),
00340                   *paddrs,
00341                   sizeof (struct in_addr));
00342 
00343   if (ACE_OS::ioctl (handle,
00344                      SIOCGARP,
00345                      &ar) == -1)
00346     {
00347       ACE_OS::close (handle);
00348       return -1;
00349     }
00350 
00351   ACE_OS::close (handle);
00352 
00353   ACE_OS::memcpy (node->node,
00354                   ar.arp_ha.sa_data,
00355                   6);
00356 
00357   return 0;
00358 
00359 #elif defined (linux) && !defined (ACE_LACKS_NETWORKING)
00360 
00361   struct ifreq ifr;
00362 
00363   ACE_HANDLE handle =
00364     ACE_OS::socket (PF_INET, SOCK_DGRAM, 0);
00365 
00366   if (handle == ACE_INVALID_HANDLE)
00367     return -1;
00368 
00369   ACE_OS::strcpy (ifr.ifr_name, "eth0");
00370 
00371   if (ACE_OS::ioctl (handle/*s*/, SIOCGIFHWADDR, &ifr) < 0)
00372     {
00373       ACE_OS::close (handle);
00374       return -1;
00375     }
00376 
00377   struct sockaddr* sa =
00378     (struct sockaddr *) &ifr.ifr_addr;
00379 
00380   ACE_OS::close (handle);
00381 
00382   ACE_OS::memcpy (node->node,
00383                   sa->sa_data,
00384                   6);
00385 
00386   return 0;
00387 
00388 #else
00389   ACE_UNUSED_ARG (node);
00390   ACE_NOTSUP_RETURN (-1);
00391 #endif
00392 }
00393 
00394 ACE_END_VERSIONED_NAMESPACE_DECL
00395 
00396 # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) && defined (ACE_LACKS_NETDB_REENTRANT_FUNCTIONS)
00397 #   include "ace/OS_NS_Thread.h"
00398 #   include "ace/Object_Manager_Base.h"
00399 
00400 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00401 
00402 int
00403 ACE_OS::netdb_acquire (void)
00404 {
00405   return ACE_OS::thread_mutex_lock ((ACE_thread_mutex_t *)
00406     ACE_OS_Object_Manager::preallocated_object[
00407       ACE_OS_Object_Manager::ACE_OS_MONITOR_LOCK]);
00408 }
00409 
00410 int
00411 ACE_OS::netdb_release (void)
00412 {
00413   return ACE_OS::thread_mutex_unlock ((ACE_thread_mutex_t *)
00414     ACE_OS_Object_Manager::preallocated_object[
00415       ACE_OS_Object_Manager::ACE_OS_MONITOR_LOCK]);
00416 }
00417 
00418 ACE_END_VERSIONED_NAMESPACE_DECL
00419 
00420 # endif /* defined (ACE_LACKS_NETDB_REENTRANT_FUNCTIONS) */
00421 

Generated on Tue Feb 2 17:18:41 2010 for ACE by  doxygen 1.4.7