posix/coil/Routing.cpp
Go to the documentation of this file.
1 // -*- C++ -*-
20 #include <stdio.h>
21 #include <netdb.h> // gethostbyname
22 #include <arpa/inet.h> // inet_ntoa
23 #include <netinet/in.h> // sockaddr_in
24 #include <sys/wait.h>
25 
26 #include <coil/Routing.h>
27 #include <coil/stringutil.h>
28 #include <coil/config_coil.h>
29 
30 namespace coil
31 {
39  bool dest_to_endpoint(std::string dest_addr, std::string& endpoint)
40  {
41  std::string dest_if;
42  if (!find_dest_ifname(dest_addr, dest_if))
43  {
44  return false;
45  }
46  return ifname_to_ipaddr(dest_if, endpoint);
47  }
48 
56  bool find_dest_ifname(std::string dest_addr, std::string& dest_if)
57  {
58  // This logic should be replaced by direct retrieving using
59  // routing interface like AFROUTE or sysctl.
60  struct ::hostent *hostent;
61  struct ::sockaddr_in addr;
62 
63  hostent = gethostbyname(dest_addr.c_str());
64  addr.sin_addr.s_addr = **(unsigned int **)(hostent->h_addr_list);
65  dest_addr = inet_ntoa(addr.sin_addr);
66 
67 #if defined(COIL_OS_FREEBSD) || defined(COIL_OS_DARWIN) || defined(COIL_OS_CYGWIN)
68  std::string cmd("PATH=/bin:/sbin:/usr/bin:/usr/sbin "
69  "route get ");
70  const char* match_str = "interface";
71  const char* delimiter = ":";
72  size_t ifname_pos(1);
73  cmd += dest_addr;
74  cmd += " 2> /dev/null";
75 #endif // COIL_OS_IS_FREEBSD || COIL_OS_DARWIN || COIL_OS_CYGWIN
76 #if defined(COIL_OS_LINUX)
77  std::string cmd("PATH=/bin:/sbin:/usr/bin:/usr/sbin "
78  "ip route get ");
79  const char* match_str = "dev ";
80  const char* delimiter = " ";
81  size_t ifname_pos(2);
82  cmd += dest_addr;
83  cmd += " 2> /dev/null";
84 #endif // COIL_OS_IS_LINUX
85 
86  FILE* fp;
87  if ((fp = popen(cmd.c_str(), "r")) == NULL)
88  {
89  return false;
90  }
91 
92  do
93  {
94  char str[512];
95  fgets(str, 512, fp);
96  std::string line(str);
97 
98  if (std::string::npos == line.find(match_str)) { continue; }
99 
100  line.erase(line.end() - 1);
101  coil::vstring vs(coil::split(line, delimiter));
102 
103 #if defined(COIL_OS_FREEBSD) || defined(COIL_OS_DARWIN) || defined(COIL_OS_CYGWIN)
104  if (vs.size() > ifname_pos)
105  {
106  dest_if = vs[ifname_pos];
107  pclose(fp);
108  wait(NULL);
109  return true;
110  }
111 #endif // COIL_OS_FREEBSD || COIL_OS_DARWIN || COIL_OS_CYGWIN
112 #if defined(COIL_OS_LINUX)
113  for (int i(0); i < vs.size(); ++i)
114  {
115  if (vs[i] == "dev")
116  {
117  dest_if = vs[i + 1];
118  return true;
119  }
120  }
121 #endif // COIL_OS_LINUX
122  } while (!feof(fp));
123  pclose(fp);
124  wait(NULL);
125  return false;
126  }
127 
135  bool ifname_to_ipaddr(std::string ifname, std::string& ipaddr)
136  {
137  std::string cmd("ifconfig ");
138  cmd += ifname;
139  cmd += " 2> /dev/null";
140 
141  FILE* fp;
142  if ((fp = popen(cmd.c_str(), "r")) == NULL)
143  {
144  return false;
145  }
146 
147  do
148  {
149  char str[512];
150  fgets(str, 512, fp);
151  std::string line(str);
152 
153  if (std::string::npos == line.find("inet ")) { continue; }
154 
155  line.erase(line.end() - 1);
156  coil::eraseHeadBlank(line);
157  coil::vstring vs(coil::split(line, " "));
158  if (vs.size() == 6)
159  {
160  ipaddr = vs[1];
161  pclose(fp);
162  wait(NULL);
163  return true;
164  }
165  } while (!feof(fp));
166  pclose(fp);
167  wait(NULL);
168  return false;
169  }
170 
171 }; // namespace coil
bool ifname_to_ipaddr(std::string ifname, std::string &ipaddr)
Get IP address from a network interface name.
void eraseHeadBlank(std::string &str)
Erase the head blank characters of string.
Definition: stringutil.cpp:262
vstring split(const std::string &input, const std::string &delimiter, bool ignore_empty)
Split string by delimiter.
Definition: stringutil.cpp:341
bool find_dest_ifname(std::string dest_addr, std::string &dest_if)
Getting network interface name from destination address.
std::vector< std::string > vstring
Definition: stringutil.h:37
list cmd
Definition: omniwxs.py:88
FILE * popen(const char *cmd, const char *mode)
void pclose(FILE *fd)
bool dest_to_endpoint(std::string dest_addr, std::string &endpoint)
Getting network interface name from destination address.
Common Object Interface Layer.


openrtm_aist
Author(s): Noriaki Ando
autogenerated on Mon Jun 10 2019 14:07:54