net_utils.cc
Go to the documentation of this file.
00001 /*
00002  * This file is part of the rc_dynamics_api package.
00003  *
00004  * Copyright (c) 2017 Roboception GmbH
00005  * All rights reserved
00006  *
00007  * Author: Christian Emmerich
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions are met:
00011  *
00012  * 1. Redistributions of source code must retain the above copyright notice,
00013  * this list of conditions and the following disclaimer.
00014  *
00015  * 2. Redistributions in binary form must reproduce the above copyright notice,
00016  * this list of conditions and the following disclaimer in the documentation
00017  * and/or other materials provided with the distribution.
00018  *
00019  * 3. Neither the name of the copyright holder nor the names of its contributors
00020  * may be used to endorse or promote products derived from this software without
00021  * specific prior written permission.
00022  *
00023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033  * POSSIBILITY OF SUCH DAMAGE.
00034  */
00035 
00036 #include "net_utils.h"
00037 
00038 #include <string.h>
00039 #include <ifaddrs.h>
00040 #include <arpa/inet.h>
00041 #include <unistd.h>
00042 
00043 namespace rc {
00044 
00045 using namespace std;
00046 
00047 uint32_t IPToUInt(const std::string ip) {
00048   int a, b, c, d;
00049   uint32_t addr = 0;
00050 
00051   if (sscanf(ip.c_str(), "%d.%d.%d.%d", &a, &b, &c, &d) != 4)
00052     return 0;
00053 
00054   addr = a << 24;
00055   addr |= b << 16;
00056   addr |= c << 8;
00057   addr |= d;
00058   return addr;
00059 }
00060 
00061 bool isIPInRange(const std::string ip, const std::string network, const std::string mask) {
00062   uint32_t ip_addr = IPToUInt(ip);
00063   uint32_t network_addr = IPToUInt(network);
00064   uint32_t mask_addr = IPToUInt(mask);
00065 
00066   uint32_t net_lower = (network_addr & mask_addr);
00067   uint32_t net_upper = (net_lower | (~mask_addr));
00068 
00069   if (ip_addr >= net_lower &&
00070       ip_addr <= net_upper)
00071     return true;
00072   return false;
00073 }
00074 
00075 
00076 bool getThisHostsIP(string &thisHostsIP,
00077                     const string &otherHostsIP,
00078                     const string &networkInterface)
00079 {
00080   // scan all network interfaces (for the desired one)
00081   struct ifaddrs *ifAddrStruct = NULL;
00082   struct ifaddrs *ifa = NULL;
00083   void *tmpAddrPtr = NULL;
00084   getifaddrs(&ifAddrStruct);
00085   bool foundValid = false;
00086   char addressBuffer[INET_ADDRSTRLEN], netmaskBuffer[INET_ADDRSTRLEN];
00087   for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next)
00088   {
00089     // check if any valid IP4 address
00090     if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_INET)
00091       continue;
00092 
00093     tmpAddrPtr = &((struct sockaddr_in *) ifa->ifa_addr)->sin_addr;
00094     inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
00095 
00096     // if user specified desired network interface
00097     if (networkInterface != "")
00098     {
00099       // check if this is the desired
00100       if (strcmp(networkInterface.c_str(), ifa->ifa_name) == 0)
00101       {
00102         foundValid = true;
00103         break;
00104       }
00105     }
00106 
00107       // we may use heuristics based on rc_visard's IP address
00108     else if (otherHostsIP != "")
00109     {
00110       tmpAddrPtr = &((struct sockaddr_in *) ifa->ifa_netmask)->sin_addr;
00111       inet_ntop(AF_INET, tmpAddrPtr, netmaskBuffer, INET_ADDRSTRLEN);
00112       if (isIPInRange(addressBuffer, otherHostsIP, netmaskBuffer))
00113       {
00114         foundValid = true;
00115         break;
00116       }
00117     }
00118 
00119       // we may use some very basic heuristics to find a 'good' interface, i.e.
00120       // simply checking the type of the interface by its name for being an
00121       // ethernet or wifi adaper
00122     else {
00123       if (  (strncmp("eth", ifa->ifa_name, 3) == 0) ||
00124             (strncmp("en", ifa->ifa_name, 2) == 0)  ||
00125             (strncmp("wl", ifa->ifa_name, 2) == 0)  )
00126       {
00127         foundValid = true;
00128         break;
00129       }
00130     }
00131   }
00132 
00133   if (foundValid)
00134     thisHostsIP = string(addressBuffer);
00135   return foundValid;
00136 }
00137 
00138 bool isValidIPAddress(const std::string &ip)
00139 {
00140   // use inet_pton to check if given string is a valid IP address
00141   static struct sockaddr_in sa;
00142   return TEMP_FAILURE_RETRY(inet_pton(AF_INET, ip.c_str(), &(sa.sin_addr))) ==
00143          1;
00144 }
00145 
00146 }


rc_visard_driver
Author(s): Heiko Hirschmueller , Christian Emmerich , Felix Ruess
autogenerated on Thu Jun 6 2019 20:43:05