Sock_Connect.cpp File Reference

#include "ace/Sock_Connect.h"
#include "ace/INET_Addr.h"
#include "ace/Log_Msg.h"
#include "ace/Handle_Set.h"
#include "ace/Auto_Ptr.h"
#include "ace/SString.h"
#include "ace/OS_Memory.h"
#include "ace/OS_NS_stdio.h"
#include "ace/OS_NS_stdlib.h"
#include "ace/OS_NS_string.h"
#include "ace/OS_NS_sys_socket.h"
#include "ace/OS_NS_netdb.h"
#include "ace/OS_NS_unistd.h"
#include "ace/os_include/net/os_if.h"
#include "ace/Guard_T.h"
#include "ace/Recursive_Thread_Mutex.h"
#include "ace/Object_Manager.h"

Include dependency graph for Sock_Connect.cpp:

Include dependency graph

Go to the source code of this file.

Defines

#define SIOCGIFCONF_CMD   SIOCGIFCONF
#define IFREQ   ifreq
#define IFCONF   ifconf
#define IFC_REQ   ifc_req
#define IFC_LEN   ifc_len
#define IFC_BUF   ifc_buf
#define IFR_ADDR   ifr_addr
#define IFR_NAME   ifr_name
#define IFR_FLAGS   ifr_flags
#define SA_FAMILY   sa_family

Functions

int get_ip_interfaces_win32 (size_t &count, ACE_INET_Addr *&addrs)
int ip_check (int &ipvn_enabled, int pf)

Variables

int ace_ipv4_enabled = -1
int ace_ipv6_enabled = -1


Define Documentation

#define IFC_BUF   ifc_buf
 

Definition at line 111 of file Sock_Connect.cpp.

#define IFC_LEN   ifc_len
 

Definition at line 110 of file Sock_Connect.cpp.

#define IFC_REQ   ifc_req
 

Definition at line 109 of file Sock_Connect.cpp.

#define IFCONF   ifconf
 

Definition at line 108 of file Sock_Connect.cpp.

Referenced by ACE::get_ip_interfaces().

#define IFR_ADDR   ifr_addr
 

Definition at line 112 of file Sock_Connect.cpp.

#define IFR_FLAGS   ifr_flags
 

Definition at line 114 of file Sock_Connect.cpp.

#define IFR_NAME   ifr_name
 

Definition at line 113 of file Sock_Connect.cpp.

#define IFREQ   ifreq
 

Definition at line 107 of file Sock_Connect.cpp.

Referenced by ACE::get_ip_interfaces().

#define SA_FAMILY   sa_family
 

Definition at line 116 of file Sock_Connect.cpp.

#define SIOCGIFCONF_CMD   SIOCGIFCONF
 

Definition at line 106 of file Sock_Connect.cpp.

Referenced by ACE::count_interfaces(), ACE::get_bcast_addr(), and ACE::get_ip_interfaces().


Function Documentation

int get_ip_interfaces_win32 size_t &  count,
ACE_INET_Addr *&  addrs
[static]
 

Definition at line 530 of file Sock_Connect.cpp.

References ACE_NEW_RETURN, ACE_NOTSUP_RETURN, ACE_TCHAR, AF_INET, AF_UNSPEC, IFF_UP, INADDR_ANY, ACE_INET_Addr::set(), SOCK_DGRAM, and ACE_OS::sprintf().

Referenced by ACE::get_ip_interfaces().

00532 {
00533 # if defined (ACE_HAS_WINCE)
00534   // moved the ACE_HAS_WINCE impl ahaid of ACE_HAS_WINSOCK2 because
00535   // WINCE in fact has winsock2, but doesn't properly support the
00536   // WSAIoctl for obtaining IPv6 address info.
00537   PIP_ADAPTER_ADDRESSES AdapterAddresses = 0;
00538   ULONG OutBufferLength = 0;
00539   ULONG RetVal = 0;
00540   unsigned char *octet_buffer = 0;
00541 
00542   RetVal =
00543     GetAdaptersAddresses(AF_UNSPEC,
00544                          0,
00545                          0,
00546                          AdapterAddresses,
00547                          &OutBufferLength);
00548 
00549   if (RetVal != ERROR_BUFFER_OVERFLOW)
00550     {
00551       return -1;
00552     }
00553 
00554   ACE_NEW_RETURN (octet_buffer, unsigned char[OutBufferLength],-1);
00555   AdapterAddresses = (IP_ADAPTER_ADDRESSES *)octet_buffer;
00556 
00557   RetVal =
00558     GetAdaptersAddresses(AF_UNSPEC,
00559                          0,
00560                          0,
00561                          AdapterAddresses,
00562                          &OutBufferLength);
00563 
00564   if (RetVal != NO_ERROR)
00565     {
00566       delete [] octet_buffer;
00567       return -1;
00568      }
00569 
00570   // If successful, output some information from the data we received
00571   PIP_ADAPTER_ADDRESSES AdapterList = AdapterAddresses;
00572   while (AdapterList)
00573     {
00574       if (AdapterList->OperStatus == IfOperStatusUp)
00575         {
00576           if (AdapterList->IfIndex != 0)
00577             ++count;
00578           if (AdapterList->Ipv6IfIndex != 0)
00579             ++count;
00580         }
00581       AdapterList = AdapterList->Next;
00582     }
00583 
00584   AdapterList = AdapterAddresses;
00585 
00586   ACE_NEW_RETURN (addrs, ACE_INET_Addr[count],-1);
00587   count = 0;
00588   for (AdapterList =  AdapterAddresses;
00589        AdapterList != 0;
00590        AdapterList = AdapterList->Next)
00591     {
00592       if (AdapterList->OperStatus != IfOperStatusUp)
00593         continue;
00594 
00595       IP_ADAPTER_UNICAST_ADDRESS *uni = 0;
00596       if (AdapterList->IfIndex != 0)
00597         for (uni = AdapterList->FirstUnicastAddress;
00598              uni != 0;
00599              uni = uni->Next)
00600           {
00601             SOCKET_ADDRESS *sa_addr = &uni->Address;
00602             if (sa_addr->lpSockaddr->sa_family == AF_INET)
00603               {
00604                 sockaddr_in *sin = (sockaddr_in*)sa_addr->lpSockaddr;
00605                 addrs[count].set(sin,sa_addr->iSockaddrLength);
00606                 ++count;
00607                 break;
00608               }
00609           }
00610       if (AdapterList->Ipv6IfIndex != 0)
00611         {
00612         for (uni = AdapterList->FirstUnicastAddress;
00613              uni != 0;
00614              uni = uni->Next)
00615             {
00616               SOCKET_ADDRESS *sa_addr = &uni->Address;
00617               if (sa_addr->lpSockaddr->sa_family == AF_INET6)
00618                 {
00619                   sockaddr_in *sin = (sockaddr_in*)sa_addr->lpSockaddr;
00620                   addrs[count].set(sin,sa_addr->iSockaddrLength);
00621                   ++count;
00622                   break;
00623                 }
00624             }
00625         }
00626     }
00627 
00628   delete [] octet_buffer;
00629   return 0;
00630 
00631 # elif defined (ACE_HAS_PHARLAP)
00632   // PharLap ETS has its own kernel routines to rummage through the device
00633   // configs and extract the interface info, but only for Pharlap RT.
00634 #   if !defined (ACE_HAS_PHARLAP_RT)
00635   ACE_NOTSUP_RETURN (-1);
00636 #   endif /* ACE_HAS_PHARLAP_RT */
00637 
00638   // Locate all of the IP devices in the system, saving a DEVHANDLE
00639   // for each. Then allocate the ACE_INET_Addrs needed and fetch all
00640   // the IP addresses.  To locate the devices, try the available
00641   // device name roots and increment the device number until the
00642   // kernel says there are no more of that type.
00643   const size_t ACE_MAX_ETS_DEVICES = 64;  // Arbitrary, but should be enough.
00644   DEVHANDLE ip_dev[ACE_MAX_ETS_DEVICES];
00645   EK_TCPIPCFG *devp;
00646   size_t i, j;
00647   ACE_TCHAR dev_name[16];
00648 
00649   count = 0;
00650   for (i = 0; count < ACE_MAX_ETS_DEVICES; i++, ++count)
00651     {
00652       // Ethernet.
00653       ACE_OS::sprintf (dev_name,
00654                        "ether%d",
00655                        i);
00656       ip_dev[count] = EtsTCPGetDeviceHandle (dev_name);
00657       if (ip_dev[count] == 0)
00658         break;
00659     }
00660   for (i = 0; count < ACE_MAX_ETS_DEVICES; i++, ++count)
00661     {
00662       // SLIP.
00663       ACE_OS::sprintf (dev_name,
00664                        "sl%d",
00665                        i);
00666       ip_dev[count] = EtsTCPGetDeviceHandle (dev_name);
00667       if (ip_dev[count] == 0)
00668         break;
00669     }
00670   for (i = 0; count < ACE_MAX_ETS_DEVICES; i++, ++count)
00671     {
00672       // PPP.
00673       ACE_OS::sprintf (dev_name,
00674                        "ppp%d",
00675                        i);
00676       ip_dev[count] = EtsTCPGetDeviceHandle (dev_name);
00677       if (ip_dev[count] == 0)
00678         break;
00679     }
00680 
00681   if (count > 0)
00682     ACE_NEW_RETURN (addrs,
00683                     ACE_INET_Addr[count],
00684                     -1);
00685   else
00686     addrs = 0;
00687 
00688   for (i = 0, j = 0; i < count; i++)
00689     {
00690       devp = EtsTCPGetDeviceCfg (ip_dev[i]);
00691       if (devp != 0)
00692         {
00693           addrs[j].set (0,
00694                         devp->nwIPAddress,
00695                         0); // Already in net order.
00696           ++j;
00697         }
00698       // There's no call to close the DEVHANDLE.
00699     }
00700 
00701   count = j;
00702   if (count == 0 && addrs != 0)
00703     {
00704       delete [] addrs;
00705       addrs = 0;
00706     }
00707 
00708   return 0;
00709 
00710 
00711 # else
00712   // All non-CE, non-Pharlap Windows. Must support Winsock2.
00713 
00714   int i, n_interfaces, status;
00715 
00716   INTERFACE_INFO info[64];
00717   SOCKET sock;
00718 
00719   // Get an (overlapped) DGRAM socket to test with
00720   sock = socket (AF_INET, SOCK_DGRAM, 0);
00721   if (sock == INVALID_SOCKET)
00722     return -1;
00723 
00724   DWORD bytes;
00725   status = WSAIoctl(sock,
00726                     SIO_GET_INTERFACE_LIST,
00727                     0,
00728                     0,
00729                     info,
00730                     sizeof(info),
00731                     &bytes,
00732                     0,
00733                     0);
00734   closesocket (sock);
00735   if (status == SOCKET_ERROR)
00736     return -1;
00737 
00738   n_interfaces = bytes / sizeof(INTERFACE_INFO);
00739 
00740   // SIO_GET_INTERFACE_LIST does not work for IPv6
00741   // Instead recent versions of Winsock2 add the new opcode
00742   // SIO_ADDRESS_LIST_QUERY.
00743   // If this is not available forget about IPv6 local interfaces:-/
00744   int n_v6_interfaces = 0;
00745 
00746 # if defined (ACE_HAS_IPV6) && defined (SIO_ADDRESS_LIST_QUERY)
00747 
00748   LPSOCKET_ADDRESS_LIST v6info;
00749   char *buffer;
00750   DWORD buflen = sizeof (SOCKET_ADDRESS_LIST) + (63 * sizeof (SOCKET_ADDRESS));
00751   ACE_NEW_RETURN (buffer,
00752                   char[buflen],
00753                   -1);
00754   v6info = reinterpret_cast<LPSOCKET_ADDRESS_LIST> (buffer);
00755 
00756   // Get an (overlapped) DGRAM socket to test with.
00757   // If it fails only return IPv4 interfaces.
00758   sock = socket (AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
00759   if (sock != INVALID_SOCKET)
00760     {
00761       status = WSAIoctl(sock,
00762                         SIO_ADDRESS_LIST_QUERY,
00763                         0,
00764                         0,
00765                         v6info,
00766                         buflen,
00767                         &bytes,
00768                         0,
00769                         0);
00770       closesocket (sock);
00771       if (status != SOCKET_ERROR)
00772         n_v6_interfaces = v6info->iAddressCount;
00773     }
00774 # endif /* ACE_HAS_IPV6 */
00775 
00776   ACE_NEW_RETURN (addrs,
00777                   ACE_INET_Addr[n_interfaces + n_v6_interfaces],
00778                   -1);
00779 
00780   // Now go through the list and transfer the good ones to the list of
00781   // because they're down or don't have an IP address.
00782   for (count = 0, i = 0; i < n_interfaces; ++i)
00783     {
00784       LPINTERFACE_INFO lpii;
00785       struct sockaddr_in *addrp = 0;
00786 
00787       lpii = &info[i];
00788       if (!(lpii->iiFlags & IFF_UP))
00789         continue;
00790 
00791       // We assume IPv4 addresses here
00792       addrp = reinterpret_cast<struct sockaddr_in *> (&lpii->iiAddress.AddressIn);
00793       if (addrp->sin_addr.s_addr == INADDR_ANY)
00794         continue;
00795 
00796       // Set the address for the caller.
00797       addrs[count].set(addrp, sizeof(sockaddr_in));
00798       ++count;
00799     }
00800 
00801 # if defined (ACE_HAS_IPV6) && defined (SIO_ADDRESS_LIST_QUERY)
00802   // Now go through the list and transfer the good ones to the list of
00803   // because they're down or don't have an IP address.
00804   for (i = 0; i < n_v6_interfaces; i++)
00805     {
00806       struct sockaddr_in6 *addr6p;
00807 
00808       if (v6info->Address[i].lpSockaddr->sa_family != AF_INET6)
00809         continue;
00810 
00811       addr6p = reinterpret_cast<struct sockaddr_in6 *> (v6info->Address[i].lpSockaddr);
00812       if (IN6_IS_ADDR_UNSPECIFIED(&addr6p->sin6_addr))  // IN6ADDR_ANY?
00813         continue;
00814 
00815       // Set the address for the caller.
00816       addrs[count].set(reinterpret_cast<struct sockaddr_in *> (addr6p), sizeof(sockaddr_in6));
00817       ++count;
00818     }
00819 
00820   delete [] buffer; // Clean up
00821 # endif /* ACE_HAS_IPV6 */
00822 
00823   if (count == 0)
00824     {
00825       delete [] addrs;
00826       addrs = 0;
00827     }
00828 
00829   return 0;
00830 
00831 # endif /* ACE_HAS_WINCE */
00832 }

int ip_check int &  ipvn_enabled,
int  pf
[static]
 

Definition at line 1590 of file Sock_Connect.cpp.

References ACE_GUARD_RETURN, ACE_OS::closesocket(), SOCK_DGRAM, and ACE_OS::socket().

01591 {
01592   // We only get to this point if ipvn_enabled was -1 in the caller.
01593   // Perform Double-Checked Locking Optimization.
01594   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
01595                             *ACE_Static_Object_Lock::instance (), 0));
01596 
01597   if (ipvn_enabled == -1)
01598     {
01599       // Determine if the kernel has IPv6 support by attempting to
01600       // create a PF_INET socket and see if it fails.
01601       ACE_HANDLE const s = ACE_OS::socket (pf, SOCK_DGRAM, 0);
01602       if (s == ACE_INVALID_HANDLE)
01603         {
01604           ipvn_enabled = 0;
01605         }
01606       else
01607         {
01608           ipvn_enabled = 1;
01609           ACE_OS::closesocket (s);
01610         }
01611     }
01612   return ipvn_enabled;
01613 }


Variable Documentation

int ace_ipv4_enabled = -1 [static]
 

Definition at line 129 of file Sock_Connect.cpp.

Referenced by ACE::ipv4_enabled().

int ace_ipv6_enabled = -1 [static]
 

Definition at line 132 of file Sock_Connect.cpp.

Referenced by ACE::ipv6_enabled().


Generated on Sun Jan 27 12:51:07 2008 for ACE by doxygen 1.3.6