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
00029
00030
00031
00032
00033
00034
00035
00036 #include "net_utils.h"
00037
00038 #include <string.h>
00039
00040 #ifdef WIN32
00041 #include <winsock2.h>
00042 #include <iphlpapi.h>
00043 #include <mstcpip.h>
00044 #pragma comment(lib, "IPHLPAPI.lib")
00045 #pragma comment(lib, "ntdll.lib")
00046 #else
00047 #include <ifaddrs.h>
00048 #include <arpa/inet.h>
00049 #include <unistd.h>
00050 #endif
00051
00052 namespace rc
00053 {
00054 using namespace std;
00055
00056 uint32_t ipToUInt(const std::string& ip)
00057 {
00058 int a, b, c, d;
00059 uint32_t addr = 0;
00060
00061 if (sscanf(ip.c_str(), "%d.%d.%d.%d", &a, &b, &c, &d) != 4)
00062 {
00063 return 0;
00064 }
00065
00066 addr = a << 24;
00067 addr |= b << 16;
00068 addr |= c << 8;
00069 addr |= d;
00070 return addr;
00071 }
00072
00073 bool isIPInRange(const std::string& ip, const std::string& network, const std::string& mask)
00074 {
00075 uint32_t ip_addr = ipToUInt(ip);
00076 uint32_t network_addr = ipToUInt(network);
00077 uint32_t mask_addr = ipToUInt(mask);
00078
00079 uint32_t net_lower = (network_addr & mask_addr);
00080 uint32_t net_upper = (net_lower | (~mask_addr));
00081
00082 if (ip_addr >= net_lower && ip_addr <= net_upper)
00083 {
00084 return true;
00085 }
00086
00087 return false;
00088 }
00089
00090 #ifdef WIN32
00091
00092 bool getThisHostsIP(string& this_hosts_ip, const string& other_hosts_ip, const string& network_interface)
00093 {
00094 this_hosts_ip = "";
00095
00096
00097
00098 DWORD dwOtherHostsIP = 0;
00099 if (other_hosts_ip.size() > 0)
00100 {
00101 dwOtherHostsIP = htonl(ipToUInt(other_hosts_ip));
00102 }
00103
00104
00105
00106 DWORD ifindex = 0xffff;
00107
00108 if (network_interface.size() > 0)
00109 {
00110 PIP_ADAPTER_ADDRESSES addr = 0;
00111 ULONG addr_size = 0;
00112
00113 for (int i = 0; i < 3; i++)
00114 {
00115 if (addr_size > 0)
00116 {
00117 addr = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(malloc(addr_size));
00118 }
00119
00120 if (addr == 0)
00121 {
00122 addr_size = 0;
00123 }
00124
00125 ULONG ret = GetAdaptersAddresses(AF_INET, 0, 0, addr, &addr_size);
00126
00127 if (ret == ERROR_SUCCESS)
00128 {
00129 break;
00130 }
00131
00132 free(addr);
00133 addr = 0;
00134 }
00135
00136 PIP_ADAPTER_ADDRESSES p = addr;
00137
00138 std::wstring wNetworkInterface(network_interface.begin(), network_interface.end());
00139
00140 while (p != 0)
00141 {
00142 if (network_interface.compare(p->AdapterName) == 0 || wNetworkInterface.compare(p->FriendlyName) == 0)
00143 {
00144 ifindex = p->IfIndex;
00145 break;
00146 }
00147
00148 p = p->Next;
00149 }
00150
00151 free(addr);
00152
00153 if (ifindex == 0xffff)
00154 {
00155 return false;
00156 }
00157 }
00158
00159
00160
00161 PMIB_IPADDRTABLE table = 0;
00162 ULONG table_size = 0;
00163
00164 for (int i = 0; i < 5; i++)
00165 {
00166 int result = GetIpAddrTable(table, &table_size, false);
00167
00168 if (result == NO_ERROR)
00169 {
00170 break;
00171 }
00172 else if (result == ERROR_INSUFFICIENT_BUFFER)
00173 {
00174 free(table);
00175 table = static_cast<PMIB_IPADDRTABLE>(malloc(table_size));
00176 }
00177 }
00178
00179 if (table == 0)
00180 {
00181 return false;
00182 }
00183
00184
00185
00186 bool found_valid = false;
00187 for (unsigned int i = 0; i < table->dwNumEntries; i++)
00188 {
00189 PMIB_IPADDRROW row = &table->table[i];
00190
00191
00192
00193 if (row->dwAddr == htonl(INADDR_LOOPBACK))
00194 {
00195 continue;
00196 }
00197
00198
00199
00200 if (ifindex == 0xffff || ifindex == row->dwIndex)
00201 {
00202
00203
00204 if ((row->dwAddr & row->dwMask) == (dwOtherHostsIP & row->dwMask))
00205 {
00206 IN_ADDR addr;
00207 char tmp[80];
00208 addr.S_un.S_addr = row->dwAddr;
00209 RtlIpv4AddressToStringA(&addr, tmp);
00210 this_hosts_ip = string(tmp);
00211
00212 found_valid = true;
00213
00214 break;
00215 }
00216 }
00217 }
00218
00219
00220
00221 free(table);
00222
00223 return found_valid;
00224 }
00225
00226 bool isValidIPAddress(const std::string& ip)
00227 {
00228 LPCTSTR tp = 0;
00229 IN_ADDR addr;
00230
00231 return RtlIpv4StringToAddressA(ip.c_str(), TRUE, &tp, &addr) == 0;
00232 }
00233
00234 #else
00235
00236 bool getThisHostsIP(string& this_hosts_ip, const string& other_hosts_ip, const string& network_interface)
00237 {
00238
00239 struct ifaddrs* if_addr_struct = NULL;
00240 struct ifaddrs* ifa = NULL;
00241 void* tmp_addr_ptr = NULL;
00242 getifaddrs(&if_addr_struct);
00243 bool found_valid = false;
00244 char address_buffer[INET_ADDRSTRLEN], netmask_buffer[INET_ADDRSTRLEN];
00245 for (ifa = if_addr_struct; ifa != NULL; ifa = ifa->ifa_next)
00246 {
00247
00248
00249 if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_INET)
00250 continue;
00251
00252 tmp_addr_ptr = &((struct sockaddr_in*)ifa->ifa_addr)->sin_addr;
00253 inet_ntop(AF_INET, tmp_addr_ptr, address_buffer, INET_ADDRSTRLEN);
00254
00255
00256
00257 if (network_interface.size() == 0 || strcmp(network_interface.c_str(), ifa->ifa_name) == 0)
00258 {
00259
00260
00261 tmp_addr_ptr = &((struct sockaddr_in*)ifa->ifa_netmask)->sin_addr;
00262 inet_ntop(AF_INET, tmp_addr_ptr, netmask_buffer, INET_ADDRSTRLEN);
00263 if (isIPInRange(address_buffer, other_hosts_ip, netmask_buffer))
00264 {
00265 found_valid = true;
00266 break;
00267 }
00268 }
00269 }
00270
00271 if (found_valid)
00272 {
00273 this_hosts_ip = string(address_buffer);
00274 }
00275
00276 return found_valid;
00277 }
00278
00279 bool isValidIPAddress(const std::string& ip)
00280 {
00281
00282 static struct sockaddr_in sa;
00283 return TEMP_FAILURE_RETRY(inet_pton(AF_INET, ip.c_str(), &(sa.sin_addr))) == 1;
00284 }
00285
00286 #endif
00287 }