OS_NS_netdb.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 // OS_NS_netdb.cpp,v 1.14 2006/01/24 12:30:29 jwillemsen Exp
00003 
00004 #include "ace/OS_NS_netdb.h"
00005 
00006 ACE_RCSID(ace, OS_NS_netdb, "OS_NS_netdb.cpp,v 1.14 2006/01/24 12:30:29 jwillemsen Exp")
00007 
00008 #if !defined (ACE_HAS_INLINED_OSCALLS)
00009 # include "ace/OS_NS_netdb.inl"
00010 #endif /* ACE_HAS_INLINED_OS_CALLS */
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   ACE_OSCALL (::hostGetByName ((char *) name), int, -1, first_addr);
00131   if (first_addr == -1)
00132     return 0;
00133 
00134   hostaddr[0] = (char *) &first_addr;
00135   hostaddr[1] = 0;
00136   aliases[0] = 0;
00137 
00138   // Might not be official: just echo input arg.
00139   ret.h_name = (char *) name;
00140   ret.h_addrtype = AF_INET;
00141   ret.h_length = 4;  // VxWorks 5.2/3 doesn't define IP_ADDR_LEN;
00142   ret.h_addr_list = hostaddr;
00143   ret.h_aliases = aliases;
00144 
00145   return &ret;
00146 }
00147 
00148 #endif /* ACE_VXWORKS && ACE_LACKS_GETHOSTBYNAME */
00149 
00150 #if defined (ACE_VXWORKS) && defined (ACE_LACKS_GETHOSTBYNAME)
00151 
00152 struct hostent *
00153 ACE_OS::gethostbyname_r (const char *name, hostent *result,
00154                          ACE_HOSTENT_DATA buffer,
00155                          int *h_errnop)
00156 {
00157   ACE_OS_TRACE ("ACE_OS::gethostbyname_r");
00158 
00159   if (ACE_OS::netdb_acquire ())
00160     return 0;
00161   else
00162     {
00163       int addr;
00164       ACE_OSCALL (::hostGetByName ((char *) name), int, -1, addr);
00165 
00166       if (addr == -1)
00167         {
00168           // errno will have been set to S_hostLib_UNKNOWN_HOST
00169           result = 0;
00170         }
00171       else
00172         {
00173           // Might not be official: just echo input arg.
00174           result->h_name = (char *) name;
00175           result->h_addrtype = AF_INET;
00176           result->h_length = 4;  // VxWorks 5.2/3 doesn't define IP_ADDR_LEN;
00177 
00178           // buffer layout:
00179           // buffer[0-3]: h_addr_list[0], pointer to the addr.
00180           // buffer[4-7]: h_addr_list[1], null terminator for the h_addr_list.
00181           // buffer[8-11]: the first (and only) addr.
00182 
00183           // Store the address list in buffer.
00184           result->h_addr_list = (char **) buffer;
00185           // Store the actual address _after_ the address list.
00186           result->h_addr_list[0] = (char *) &result->h_addr_list[2];
00187           result->h_addr_list[2] = (char *) addr;
00188           // Null-terminate the list of addresses.
00189           result->h_addr_list[1] = 0;
00190           // And no aliases, so null-terminate h_aliases.
00191           result->h_aliases = &result->h_addr_list[1];
00192         }
00193     }
00194 
00195   ACE_OS::netdb_release ();
00196   *h_errnop = errno;
00197   return result;
00198 }
00199 
00200 #endif /* ACE_VXWORKS && ACE_LACKS_GETHOSTBYNAME*/
00201 
00202 ACE_END_VERSIONED_NAMESPACE_DECL
00203 
00204 // Include if_arp so that getmacaddr can use the
00205 // arp structure.
00206 #if defined (sun)
00207 # include /**/ <net/if_arp.h>
00208 #endif
00209 
00210 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00211 
00212 int
00213 ACE_OS::getmacaddress (struct macaddr_node_t *node)
00214 {
00215   ACE_OS_TRACE ("ACE_OS::getmacaddress");
00216 
00217 #if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
00218 # if !defined (ACE_HAS_PHARLAP)
00219     /** Define a structure for use with the netbios routine */
00220     struct ADAPTERSTAT
00221     {
00222       ADAPTER_STATUS adapt;
00223       NAME_BUFFER    NameBuff [30];
00224     };
00225 
00226     NCB         ncb;
00227     LANA_ENUM   lenum;
00228     unsigned char result;
00229 
00230     ACE_OS::memset (&ncb, 0, sizeof(ncb));
00231     ncb.ncb_command = NCBENUM;
00232     ncb.ncb_buffer  = reinterpret_cast<unsigned char*> (&lenum);
00233     ncb.ncb_length  = sizeof(lenum);
00234 
00235     result = Netbios (&ncb);
00236 
00237     for(int i = 0; i < lenum.length; i++)
00238       {
00239         ACE_OS::memset (&ncb, 0, sizeof(ncb));
00240         ncb.ncb_command  = NCBRESET;
00241         ncb.ncb_lana_num = lenum.lana [i];
00242 
00243         /** Reset the netbios */
00244         result = Netbios (&ncb);
00245 
00246         if (ncb.ncb_retcode != NRC_GOODRET)
00247         {
00248           return -1;
00249         }
00250 
00251         ADAPTERSTAT adapter;
00252         ACE_OS::memset (&ncb, 0, sizeof (ncb));
00253         ACE_OS::strcpy (reinterpret_cast<char*> (ncb.ncb_callname), "*");
00254         ncb.ncb_command     = NCBASTAT;
00255         ncb.ncb_lana_num    = lenum.lana[i];
00256         ncb.ncb_buffer      = reinterpret_cast<unsigned char*> (&adapter);
00257         ncb.ncb_length      = sizeof (adapter);
00258 
00259         result = Netbios (&ncb);
00260 
00261         if (result == 0)
00262         {
00263           ACE_OS::memcpy (node->node,
00264               adapter.adapt.adapter_address,
00265               6);
00266           return 0;
00267         }
00268       }
00269     return 0;
00270 # else
00271 #   if defined (ACE_HAS_PHARLAP_RT)
00272       DEVHANDLE ip_dev = (DEVHANDLE)0;
00273       EK_TCPIPCFG *devp;
00274       size_t i;
00275       ACE_TCHAR dev_name[16];
00276 
00277       for (i = 0; i < 10; i++)
00278         {
00279           // Ethernet.
00280           ACE_OS::sprintf (dev_name,
00281                            "ether%d",
00282                            i);
00283           ip_dev = EtsTCPGetDeviceHandle (dev_name);
00284           if (ip_dev != 0)
00285             break;
00286         }
00287       if (ip_dev == 0)
00288         return -1;
00289       devp = EtsTCPGetDeviceCfg (ip_dev);
00290       if (devp == 0)
00291         return -1;
00292       ACE_OS::memcpy (node->node,
00293             &devp->EthernetAddress[0],
00294             6);
00295       return 0;
00296 #   else
00297       ACE_UNUSED_ARG (node);
00298       ACE_NOTSUP_RETURN (-1);
00299 #   endif /* ACE_HAS_PHARLAP_RT */
00300 # endif /* ACE_HAS_PHARLAP */
00301 #elif defined (sun)
00302 
00303   /** obtain the local host name */
00304   char hostname [MAXHOSTNAMELEN];
00305   ACE_OS::hostname (hostname, sizeof (hostname));
00306 
00307   /** Get the hostent to use with ioctl */
00308   struct hostent *phost =
00309     ACE_OS::gethostbyname (hostname);
00310 
00311   if (phost == 0)
00312     return -1;
00313 
00314   ACE_HANDLE handle =
00315     ACE_OS::socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
00316 
00317   if (handle == ACE_INVALID_HANDLE)
00318     return -1;
00319 
00320   char **paddrs = phost->h_addr_list;
00321 
00322   struct arpreq ar;
00323 
00324   struct sockaddr_in *psa =
00325     (struct sockaddr_in *)&(ar.arp_pa);
00326 
00327   ACE_OS::memset (&ar,
00328                   0,
00329                   sizeof (struct arpreq));
00330 
00331   psa->sin_family = AF_INET;
00332 
00333   ACE_OS::memcpy (&(psa->sin_addr),
00334                   *paddrs,
00335                   sizeof (struct in_addr));
00336 
00337   if (ACE_OS::ioctl (handle,
00338                      SIOCGARP,
00339                      &ar) == -1)
00340     {
00341       ACE_OS::close (handle);
00342       return -1;
00343     }
00344 
00345   ACE_OS::close (handle);
00346 
00347   ACE_OS::memcpy (node->node,
00348                   ar.arp_ha.sa_data,
00349                   6);
00350 
00351   return 0;
00352 
00353 #elif defined (linux)
00354 
00355   struct ifreq ifr;
00356 
00357   ACE_HANDLE handle =
00358     ACE_OS::socket (PF_INET, SOCK_DGRAM, 0);
00359 
00360   if (handle == ACE_INVALID_HANDLE)
00361     return -1;
00362 
00363   ACE_OS::strcpy (ifr.ifr_name, "eth0");
00364 
00365   if (ACE_OS::ioctl (handle/*s*/, SIOCGIFHWADDR, &ifr) < 0)
00366     {
00367       ACE_OS::close (handle);
00368       return -1;
00369     }
00370 
00371   struct sockaddr* sa =
00372     (struct sockaddr *) &ifr.ifr_addr;
00373 
00374   ACE_OS::close (handle);
00375 
00376   ACE_OS::memcpy (node->node,
00377                   sa->sa_data,
00378                   6);
00379 
00380   return 0;
00381 
00382 #else
00383   ACE_UNUSED_ARG (node);
00384   ACE_NOTSUP_RETURN (-1);
00385 #endif
00386 }
00387 
00388 ACE_END_VERSIONED_NAMESPACE_DECL
00389 
00390 # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) && defined (ACE_LACKS_NETDB_REENTRANT_FUNCTIONS)
00391 #   include "ace/OS_NS_Thread.h"
00392 #   include "ace/Object_Manager_Base.h"
00393 
00394 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00395 
00396 int
00397 ACE_OS::netdb_acquire (void)
00398 {
00399   return ACE_OS::thread_mutex_lock ((ACE_thread_mutex_t *)
00400     ACE_OS_Object_Manager::preallocated_object[
00401       ACE_OS_Object_Manager::ACE_OS_MONITOR_LOCK]);
00402 }
00403 
00404 int
00405 ACE_OS::netdb_release (void)
00406 {
00407   return ACE_OS::thread_mutex_unlock ((ACE_thread_mutex_t *)
00408     ACE_OS_Object_Manager::preallocated_object[
00409       ACE_OS_Object_Manager::ACE_OS_MONITOR_LOCK]);
00410 }
00411 
00412 ACE_END_VERSIONED_NAMESPACE_DECL
00413 
00414 # endif /* defined (ACE_LACKS_NETDB_REENTRANT_FUNCTIONS) */
00415 

Generated on Thu Nov 9 09:41:57 2006 for ACE by doxygen 1.3.6