Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "config.h"
00029 #include "ros/network.h"
00030 #include "ros/file_log.h"
00031 #include "ros/exceptions.h"
00032 #include "ros/io.h"
00033 #include <ros/console.h>
00034 #include <ros/assert.h>
00035 #ifdef HAVE_IFADDRS_H
00036 #include <ifaddrs.h>
00037 #endif
00038
00039 #include <boost/lexical_cast.hpp>
00040
00041 namespace ros
00042 {
00043
00044 namespace network
00045 {
00046
00047 std::string g_host;
00048 uint16_t g_tcpros_server_port = 0;
00049
00050 const std::string& getHost()
00051 {
00052 return g_host;
00053 }
00054
00055 bool splitURI(const std::string& uri, std::string& host, uint32_t& port)
00056 {
00057
00058 if (uri.substr(0, 7) == std::string("http://"))
00059 host = uri.substr(7);
00060 else if (uri.substr(0, 9) == std::string("rosrpc://"))
00061 host = uri.substr(9);
00062
00063 std::string::size_type colon_pos = host.find_first_of(":");
00064 if (colon_pos == std::string::npos)
00065 return false;
00066 std::string port_str = host.substr(colon_pos+1);
00067 std::string::size_type slash_pos = port_str.find_first_of("/");
00068 if (slash_pos != std::string::npos)
00069 port_str = port_str.erase(slash_pos);
00070 port = atoi(port_str.c_str());
00071 host = host.erase(colon_pos);
00072 return true;
00073 }
00074
00075 uint16_t getTCPROSPort()
00076 {
00077 return g_tcpros_server_port;
00078 }
00079
00080 static bool isPrivateIP(const char *ip)
00081 {
00082 bool b = !strncmp("192.168", ip, 7) || !strncmp("10.", ip, 3) ||
00083 !strncmp("169.254", ip, 7);
00084 return b;
00085 }
00086
00087 std::string determineHost()
00088 {
00089 std::string ip_env;
00090
00091 if ( get_environment_variable(ip_env, "ROS_HOSTNAME")) {
00092 ROSCPP_LOG_DEBUG( "determineIP: using value of ROS_HOSTNAME:%s:", ip_env.c_str());
00093 if (ip_env.size() == 0)
00094 {
00095 ROS_WARN("invalid ROS_HOSTNAME (an empty string)");
00096 }
00097 return ip_env;
00098 }
00099
00100
00101 if ( get_environment_variable(ip_env, "ROS_IP")) {
00102 ROSCPP_LOG_DEBUG( "determineIP: using value of ROS_IP:%s:", ip_env.c_str());
00103 if (ip_env.size() == 0)
00104 {
00105 ROS_WARN("invalid ROS_IP (an empty string)");
00106 }
00107 return ip_env;
00108 }
00109
00110
00111 char host[1024];
00112 memset(host,0,sizeof(host));
00113 if(gethostname(host,sizeof(host)-1) != 0)
00114 {
00115 ROS_ERROR("determineIP: gethostname failed");
00116 }
00117
00118 else if(strlen(host) && strcmp("localhost", host))
00119 {
00120 return std::string(host);
00121 }
00122
00123
00124
00125 #ifdef HAVE_IFADDRS_H
00126 struct ifaddrs *ifa = NULL, *ifp = NULL;
00127 int rc;
00128 if ((rc = getifaddrs(&ifp)) < 0)
00129 {
00130 ROS_FATAL("error in getifaddrs: [%s]", strerror(rc));
00131 ROS_BREAK();
00132 }
00133 char preferred_ip[200] = {0};
00134 for (ifa = ifp; ifa; ifa = ifa->ifa_next)
00135 {
00136 char ip_[200];
00137 socklen_t salen;
00138 if (!ifa->ifa_addr)
00139 continue;
00140 if (ifa->ifa_addr->sa_family == AF_INET)
00141 salen = sizeof(struct sockaddr_in);
00142 else if (ifa->ifa_addr->sa_family == AF_INET6)
00143 salen = sizeof(struct sockaddr_in6);
00144 else
00145 continue;
00146 if (getnameinfo(ifa->ifa_addr, salen, ip_, sizeof(ip_), NULL, 0,
00147 NI_NUMERICHOST) < 0)
00148 {
00149 ROSCPP_LOG_DEBUG( "getnameinfo couldn't get the ip of interface [%s]", ifa->ifa_name);
00150 continue;
00151 }
00152
00153
00154 if (!strcmp("127.0.0.1", ip_) || strchr(ip_,':'))
00155 continue;
00156 if (ifa->ifa_addr->sa_family == AF_INET6 && !preferred_ip[0])
00157 strcpy(preferred_ip, ip_);
00158 else if (isPrivateIP(ip_) && !preferred_ip[0])
00159 strcpy(preferred_ip, ip_);
00160 else if (!isPrivateIP(ip_) &&
00161 (isPrivateIP(preferred_ip) || !preferred_ip[0]))
00162 strcpy(preferred_ip, ip_);
00163 }
00164 freeifaddrs(ifp);
00165 if (!preferred_ip[0])
00166 {
00167 ROS_ERROR( "Couldn't find a preferred IP via the getifaddrs() call; I'm assuming that your IP "
00168 "address is 127.0.0.1. This should work for local processes, "
00169 "but will almost certainly not work if you have remote processes."
00170 "Report to the ROS development team to seek a fix.");
00171 return std::string("127.0.0.1");
00172 }
00173 ROSCPP_LOG_DEBUG( "preferred IP is guessed to be %s", preferred_ip);
00174 return std::string(preferred_ip);
00175 #else
00176
00177
00178 ROS_ERROR( "You don't have the getifaddrs() call; I'm assuming that your IP "
00179 "address is 127.0.0.1. This should work for local processes, "
00180 "but will almost certainly not work if you have remote processes."
00181 "Report to the ROS development team to seek a fix.");
00182 return std::string("127.0.0.1");
00183 #endif
00184 }
00185
00186 void init(const M_string& remappings)
00187 {
00188 M_string::const_iterator it = remappings.find("__hostname");
00189 if (it != remappings.end())
00190 {
00191 g_host = it->second;
00192 }
00193 else
00194 {
00195 it = remappings.find("__ip");
00196 if (it != remappings.end())
00197 {
00198 g_host = it->second;
00199 }
00200 }
00201
00202 it = remappings.find("__tcpros_server_port");
00203 if (it != remappings.end())
00204 {
00205 try
00206 {
00207 g_tcpros_server_port = boost::lexical_cast<uint16_t>(it->second);
00208 }
00209 catch (boost::bad_lexical_cast&)
00210 {
00211 throw ros::InvalidPortException("__tcpros_server_port [" + it->second + "] was not specified as a number within the 0-65535 range");
00212 }
00213 }
00214
00215 if (g_host.empty())
00216 {
00217 g_host = determineHost();
00218 }
00219 }
00220
00221 }
00222
00223 }
roscpp
Author(s): Morgan Quigley, Josh Faust, Brian Gerkey, Troy Straszheim
autogenerated on Fri Aug 28 2015 12:33:10