#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:
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 |
|
Definition at line 111 of file Sock_Connect.cpp. |
|
Definition at line 110 of file Sock_Connect.cpp. |
|
Definition at line 109 of file Sock_Connect.cpp. |
|
Definition at line 108 of file Sock_Connect.cpp. Referenced by ACE::get_ip_interfaces(). |
|
Definition at line 112 of file Sock_Connect.cpp. |
|
Definition at line 114 of file Sock_Connect.cpp. |
|
Definition at line 113 of file Sock_Connect.cpp. |
|
Definition at line 107 of file Sock_Connect.cpp. Referenced by ACE::get_ip_interfaces(). |
|
Definition at line 116 of file Sock_Connect.cpp. |
|
Definition at line 106 of file Sock_Connect.cpp. Referenced by ACE::count_interfaces(), ACE::get_bcast_addr(), and ACE::get_ip_interfaces(). |
|
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 } |
|
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 } |
|
Definition at line 129 of file Sock_Connect.cpp. Referenced by ACE::ipv4_enabled(). |
|
Definition at line 132 of file Sock_Connect.cpp. Referenced by ACE::ipv6_enabled(). |