// [License] // The Ariba-Underlay Copyright // // Copyright (c) 2008-2009, Institute of Telematics, Universität Karlsruhe (TH) // // Institute of Telematics // Universität Karlsruhe (TH) // Zirkel 2, 76128 Karlsruhe // Germany // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE INSTITUTE OF TELEMATICS ``AS IS'' AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ARIBA PROJECT OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // The views and conclusions contained in the software and documentation // are those of the authors and should not be interpreted as representing // official policies, either expressed or implied, of the Institute of // Telematics. // [License] #include "AddressDiscovery.h" #include "ariba/config.h" #include #include #include #include #include #include #include #include #include #include #include #include "ariba/utility/addressing2/tcpip_endpoint.hpp" #include "ariba/utility/addressing/mac_address.hpp" #ifdef HAVE_LIBBLUETOOTH #include #include #include #endif namespace ariba { namespace communication { using namespace std; using namespace addressing2; using namespace boost::asio::ip; using ariba::addressing::mac_address; mac_address getMacFromIF( const char* name ) { mac_address addr; #ifdef HAVE_LIBBLUETOOTH int s; struct ifreq buffer; s = socket(PF_INET, SOCK_DGRAM, 0); memset(&buffer, 0x00, sizeof(buffer)); strcpy(buffer.ifr_name, name); ioctl(s, SIOCGIFHWADDR, &buffer); close(s); addr.assign( (uint8_t*)buffer.ifr_hwaddr.sa_data, 6 ); #endif return addr; } int dev_info(int s, int dev_id, long arg) { #ifdef HAVE_LIBBLUETOOTH // endpoint_set* set = (endpoint_set*)arg; // struct hci_dev_info di; // memset(&di, 0, sizeof(struct hci_dev_info)); // di.dev_id = dev_id; // if (ioctl(s, HCIGETDEVINFO, (void *) &di)) return 0; // mac_address mac; // mac.bluetooth( di.bdaddr ); // address_vf vf = mac; // set->add(vf); #endif return 0; } void discover_bluetooth( EndpointSetPtr listenOn_endpoints, EndpointSetPtr discovered_endpoints ) { #ifdef HAVE_LIBBLUETOOTH // FIXME aktuell bluetooth // hci_for_each_dev(HCI_UP, &AddressDiscovery::dev_info, (long)&endpoints ); #endif } void discover_ip_addresses( EndpointSetPtr listenOn_endpoints, EndpointSetPtr discovered_endpoints ) { bool discover_ipv4 = false; bool discover_ipv6 = false; vector ipv4_ports; vector ipv6_ports; /* analyze listenOn_endpoints */ BOOST_FOREACH( TcpIP_EndpointPtr endp, listenOn_endpoints->get_tcpip_endpoints() ) { // BRANCH: IPv4 any [0.0.0.0] if ( endp->to_asio().address() == address_v4::any() ) { // add port ipv4_ports.push_back(endp->to_asio().port()); discover_ipv4 = true; } // BRANCH: IPv6 any [::] else if ( endp->to_asio().address() == address_v6::any() ) { // add port ipv6_ports.push_back(endp->to_asio().port()); discover_ipv6 = true; // NOTE: on linux the ipv6-any address [::] catches ipv4 as well ipv4_ports.push_back(endp->to_asio().port()); discover_ipv4 = true; } // BRANCH: explicit ip address else { // ---> don't discover anything, just add it directly discovered_endpoints->add_endpoint(endp); } } /* discover addresses */ if ( discover_ipv4 || discover_ipv6 ) { struct ifaddrs* ifaceBuffer = NULL; void* tmpAddrPtr = NULL; int ret = getifaddrs( &ifaceBuffer ); if( ret != 0 ) return; for( struct ifaddrs* i=ifaceBuffer; i != NULL; i=i->ifa_next ) { // ignore devices that are disabled or have no ip if(i == NULL) continue; struct sockaddr* addr = i->ifa_addr; if (addr==NULL) continue; // // ignore tun devices // XXX why? // string device = string(i->ifa_name); // if(device.find_first_of("tun") == 0) continue; // IPv4 if ( discover_ipv4 && addr->sa_family == AF_INET ) { char straddr[INET_ADDRSTRLEN]; tmpAddrPtr= &((struct sockaddr_in*)addr)->sin_addr; inet_ntop( i->ifa_addr->sa_family, tmpAddrPtr, straddr, sizeof(straddr) ); address ip_addr = address::from_string(straddr); // skip loopback address if ( ip_addr.to_v4() == address_v4::loopback() ) continue; // add endpoint for this address and every given ipv4 port BOOST_FOREACH( uint16_t port, ipv4_ports ) { tcp::endpoint tcpip_endp(ip_addr, port); TcpIP_EndpointPtr endp(new tcpip_endpoint(tcpip_endp)); discovered_endpoints->add_endpoint(endp); } } // IPv6 else if ( discover_ipv6 && addr->sa_family == AF_INET6 ) { // look for ipv6 char straddr[INET6_ADDRSTRLEN]; tmpAddrPtr= &((struct sockaddr_in6*)addr)->sin6_addr; inet_ntop( i->ifa_addr->sa_family, tmpAddrPtr, straddr, sizeof(straddr) ); address ip_addr = address::from_string(straddr); // skip loopback address if ( ip_addr.to_v6() == address_v6::loopback() ) continue; // add endpoint for this address and every given ipv4 port BOOST_FOREACH( uint16_t port, ipv6_ports ) { tcp::endpoint tcpip_endp(ip_addr, port); TcpIP_EndpointPtr endp(new tcpip_endpoint(tcpip_endp)); discovered_endpoints->add_endpoint(endp); } } } freeifaddrs(ifaceBuffer); } } EndpointSetPtr AddressDiscovery::discover_endpoints(EndpointSetPtr listenOn_endpoints) { EndpointSetPtr discovered_endpoints(new addressing2::endpoint_set()); discover_ip_addresses( listenOn_endpoints, discovered_endpoints ); discover_bluetooth( listenOn_endpoints, discovered_endpoints ); return discovered_endpoints; } }} // namespace ariba, communication