Go to the documentation of this file.00001
00020 #include <stdio.h>
00021 #include <netdb.h>
00022 #include <arpa/inet.h>
00023 #include <netinet/in.h>
00024 #include <sys/wait.h>
00025
00026 #include <coil/Routing.h>
00027 #include <coil/stringutil.h>
00028 #include <coil/config_coil.h>
00029
00030 namespace coil
00031 {
00039 bool dest_to_endpoint(std::string dest_addr, std::string& endpoint)
00040 {
00041 std::string dest_if;
00042 if (!find_dest_ifname(dest_addr, dest_if))
00043 {
00044 return false;
00045 }
00046 return ifname_to_ipaddr(dest_if, endpoint);
00047 }
00048
00056 bool find_dest_ifname(std::string dest_addr, std::string& dest_if)
00057 {
00058
00059
00060 struct ::hostent *hostent;
00061 struct ::sockaddr_in addr;
00062
00063 hostent = gethostbyname(dest_addr.c_str());
00064 addr.sin_addr.s_addr = **(unsigned int **)(hostent->h_addr_list);
00065 dest_addr = inet_ntoa(addr.sin_addr);
00066
00067 #if defined(COIL_OS_FREEBSD) || defined(COIL_OS_DARWIN) || defined(COIL_OS_CYGWIN)
00068 std::string cmd("PATH=/bin:/sbin:/usr/bin:/usr/sbin "
00069 "route get ");
00070 const char* match_str = "interface";
00071 const char* delimiter = ":";
00072 size_t ifname_pos(1);
00073 cmd += dest_addr;
00074 cmd += " 2> /dev/null";
00075 #endif // COIL_OS_IS_FREEBSD || COIL_OS_DARWIN || COIL_OS_CYGWIN
00076 #if defined(COIL_OS_LINUX)
00077 std::string cmd("PATH=/bin:/sbin:/usr/bin:/usr/sbin "
00078 "ip route get ");
00079 const char* match_str = "dev ";
00080 const char* delimiter = " ";
00081 size_t ifname_pos(2);
00082 cmd += dest_addr;
00083 cmd += " 2> /dev/null";
00084 #endif // COIL_OS_IS_LINUX
00085
00086 FILE* fp;
00087 if ((fp = popen(cmd.c_str(), "r")) == NULL)
00088 {
00089 return false;
00090 }
00091
00092 do
00093 {
00094 char str[512];
00095 fgets(str, 512, fp);
00096 std::string line(str);
00097
00098 if (std::string::npos == line.find(match_str)) { continue; }
00099
00100 line.erase(line.end() - 1);
00101 coil::vstring vs(coil::split(line, delimiter));
00102
00103 #if defined(COIL_OS_FREEBSD) || defined(COIL_OS_DARWIN) || defined(COIL_OS_CYGWIN)
00104 if (vs.size() > ifname_pos)
00105 {
00106 dest_if = vs[ifname_pos];
00107 pclose(fp);
00108 wait(NULL);
00109 return true;
00110 }
00111 #endif // COIL_OS_FREEBSD || COIL_OS_DARWIN || COIL_OS_CYGWIN
00112 #if defined(COIL_OS_LINUX)
00113 for (int i(0); i < vs.size(); ++i)
00114 {
00115 if (vs[i] == "dev")
00116 {
00117 dest_if = vs[i + 1];
00118 return true;
00119 }
00120 }
00121 #endif // COIL_OS_LINUX
00122 } while (!feof(fp));
00123 pclose(fp);
00124 wait(NULL);
00125 return false;
00126 }
00127
00135 bool ifname_to_ipaddr(std::string ifname, std::string& ipaddr)
00136 {
00137 std::string cmd("ifconfig ");
00138 cmd += ifname;
00139 cmd += " 2> /dev/null";
00140
00141 FILE* fp;
00142 if ((fp = popen(cmd.c_str(), "r")) == NULL)
00143 {
00144 return false;
00145 }
00146
00147 do
00148 {
00149 char str[512];
00150 fgets(str, 512, fp);
00151 std::string line(str);
00152
00153 if (std::string::npos == line.find("inet ")) { continue; }
00154
00155 line.erase(line.end() - 1);
00156 coil::eraseHeadBlank(line);
00157 coil::vstring vs(coil::split(line, " "));
00158 if (vs.size() == 6)
00159 {
00160 ipaddr = vs[1];
00161 pclose(fp);
00162 wait(NULL);
00163 return true;
00164 }
00165 } while (!feof(fp));
00166 pclose(fp);
00167 wait(NULL);
00168 return false;
00169 }
00170
00171 };