| 1 |
/* IP2Location.c |
|---|
| 2 |
* |
|---|
| 3 |
* Copyright (C) 2005-2007 IP2Location.com All Rights Reserved. |
|---|
| 4 |
* |
|---|
| 5 |
* http://www.ip2location.com |
|---|
| 6 |
* |
|---|
| 7 |
* This library is free software; you can redistribute it and/or |
|---|
| 8 |
* modify it under the terms of the GNU General Public |
|---|
| 9 |
* License as published by the Free Software Foundation; either |
|---|
| 10 |
* version 2 of the License, or (at your option) any later version. |
|---|
| 11 |
* |
|---|
| 12 |
* This library is distributed in the hope that it will be useful, |
|---|
| 13 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 14 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 15 |
* General Public License for more details. |
|---|
| 16 |
* |
|---|
| 17 |
* You should have received a copy of the GNU General Public |
|---|
| 18 |
* License along with this library; if not, write to the Free Software |
|---|
| 19 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 20 |
* |
|---|
| 21 |
*/ |
|---|
| 22 |
|
|---|
| 23 |
#include <stdint.h> |
|---|
| 24 |
#include <strings.h> |
|---|
| 25 |
#include <sys/socket.h> |
|---|
| 26 |
#include <netinet/in.h> |
|---|
| 27 |
#include <arpa/inet.h> |
|---|
| 28 |
|
|---|
| 29 |
#include <string.h> |
|---|
| 30 |
#include <stdio.h> |
|---|
| 31 |
|
|---|
| 32 |
|
|---|
| 33 |
#include "common/math/imath.h" |
|---|
| 34 |
#include "IP2Location.h" |
|---|
| 35 |
|
|---|
| 36 |
|
|---|
| 37 |
////////////////////////////////////////////////////////////////////// |
|---|
| 38 |
// |
|---|
| 39 |
// Private Functions |
|---|
| 40 |
// |
|---|
| 41 |
int IP2Location_initialize(IP2Location *loc); |
|---|
| 42 |
IP2LocationRecord *IP2Location_new_record(); |
|---|
| 43 |
char* IP2Location_read128(FILE *handle, uint32 position); |
|---|
| 44 |
uint32 IP2Location_read32(FILE *handle, uint32 position); |
|---|
| 45 |
uint8 IP2Location_read8(FILE *handle, uint32 position); |
|---|
| 46 |
char *IP2Location_readStr(FILE *handle, uint32 position); |
|---|
| 47 |
float IP2Location_readFloat(FILE *handle, uint32 position); |
|---|
| 48 |
uint32 IP2Location_ip2no(const char* ip); |
|---|
| 49 |
mpz IP2Location_ipv6_to_no(const char* ip); |
|---|
| 50 |
int IP2Location_ip_is_ipv4 (const char* ipaddr); |
|---|
| 51 |
int IP2Location_ip_is_ipv6 (const char* ipaddr); |
|---|
| 52 |
IP2LocationRecord *IP2Location_get_record(IP2Location *loc, |
|---|
| 53 |
const char* ip, uint32 mode); |
|---|
| 54 |
IP2LocationRecord *IP2Location_get_ipv6_record(IP2Location *loc, |
|---|
| 55 |
const char* ipstring, uint32 mode); |
|---|
| 56 |
char* IP2Location_mp2string (mpz mp); |
|---|
| 57 |
StringList* IP2Location_split(const char* delimiters, |
|---|
| 58 |
const char* targetString, |
|---|
| 59 |
unsigned int flags, int limit); |
|---|
| 60 |
char* IP2Location_replace(const char* substr, |
|---|
| 61 |
const char* replace, |
|---|
| 62 |
const char* targetString); |
|---|
| 63 |
unsigned int IP2Location_substr_count(const char* substr, |
|---|
| 64 |
const char* targetString); |
|---|
| 65 |
unsigned int StringListCount (StringList* toCount); |
|---|
| 66 |
void FreeStringList (StringList* toFree); |
|---|
| 67 |
|
|---|
| 68 |
uint8_t COUNTRY_POSITION[15] = {0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; |
|---|
| 69 |
uint8_t REGION_POSITION[15] = {0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}; |
|---|
| 70 |
uint8_t CITY_POSITION[15] = {0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}; |
|---|
| 71 |
uint8_t ISP_POSITION[15] = {0, 0, 3, 0, 5, 0, 7, 5, 7, 0, 8, 0, 9, 0, 9}; |
|---|
| 72 |
uint8_t LATITUDE_POSITION[15] = {0, 0, 0, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5}; |
|---|
| 73 |
uint8_t LONGITUDE_POSITION[15] = {0, 0, 0, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 6, 6}; |
|---|
| 74 |
uint8_t DOMAIN_POSITION[15] = {0, 0, 0, 0, 0, 0, 0, 6, 8, 0, 9, 0, 10,0, 10}; |
|---|
| 75 |
uint8_t ZIPCODE_POSITION[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 7}; |
|---|
| 76 |
uint8_t TIMEZONE_POSITION[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 7, 8}; |
|---|
| 77 |
uint8_t NETSPEED_POSITION[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 11}; |
|---|
| 78 |
|
|---|
| 79 |
IP2Location *IP2Location_open(const char* db) { |
|---|
| 80 |
FILE *f; |
|---|
| 81 |
IP2Location *loc; |
|---|
| 82 |
|
|---|
| 83 |
if ((f=fopen(db,"rb")) == NULL) { |
|---|
| 84 |
LOG_ERROR << "IP2Location library error in opening database: " << db; |
|---|
| 85 |
return NULL; |
|---|
| 86 |
} |
|---|
| 87 |
|
|---|
| 88 |
loc = (IP2Location *) malloc(sizeof(IP2Location)); |
|---|
| 89 |
memset(loc, 0, sizeof(IP2Location)); |
|---|
| 90 |
|
|---|
| 91 |
loc->filehandle = f; |
|---|
| 92 |
|
|---|
| 93 |
IP2Location_initialize(loc); |
|---|
| 94 |
|
|---|
| 95 |
return loc; |
|---|
| 96 |
} |
|---|
| 97 |
|
|---|
| 98 |
|
|---|
| 99 |
uint32 IP2Location_close(IP2Location *loc) { |
|---|
| 100 |
if (loc->filehandle != NULL) { |
|---|
| 101 |
fclose(loc->filehandle); |
|---|
| 102 |
} |
|---|
| 103 |
if (loc != NULL) { |
|---|
| 104 |
free(loc); |
|---|
| 105 |
} |
|---|
| 106 |
return 0; |
|---|
| 107 |
} |
|---|
| 108 |
|
|---|
| 109 |
|
|---|
| 110 |
int IP2Location_initialize(IP2Location *loc) { |
|---|
| 111 |
loc->databasetype = IP2Location_read8(loc->filehandle, 1); |
|---|
| 112 |
loc->databasecolumn = IP2Location_read8(loc->filehandle, 2); |
|---|
| 113 |
loc->databaseyear = IP2Location_read8(loc->filehandle, 3); |
|---|
| 114 |
loc->databasemonth = IP2Location_read8(loc->filehandle, 4); |
|---|
| 115 |
loc->databaseday = IP2Location_read8(loc->filehandle, 5); |
|---|
| 116 |
loc->databasecount = IP2Location_read32(loc->filehandle, 6); |
|---|
| 117 |
loc->databaseaddr = IP2Location_read32(loc->filehandle, 10); |
|---|
| 118 |
loc->ipversion = IP2Location_read32(loc->filehandle, 14); |
|---|
| 119 |
return 0; |
|---|
| 120 |
} |
|---|
| 121 |
|
|---|
| 122 |
|
|---|
| 123 |
IP2LocationRecord *IP2Location_get_country_short(IP2Location *loc, |
|---|
| 124 |
const char* ip) |
|---|
| 125 |
{ |
|---|
| 126 |
if (loc->ipversion == IPV6) { |
|---|
| 127 |
return IP2Location_get_ipv6_record(loc, ip, COUNTRYSHORT); |
|---|
| 128 |
} else { |
|---|
| 129 |
return IP2Location_get_record(loc, ip, COUNTRYSHORT); |
|---|
| 130 |
} |
|---|
| 131 |
} |
|---|
| 132 |
|
|---|
| 133 |
|
|---|
| 134 |
IP2LocationRecord *IP2Location_get_country_long(IP2Location *loc, |
|---|
| 135 |
const char* ip) |
|---|
| 136 |
{ |
|---|
| 137 |
if (loc->ipversion == IPV6) { |
|---|
| 138 |
return IP2Location_get_ipv6_record(loc, ip, COUNTRYLONG); |
|---|
| 139 |
} else { |
|---|
| 140 |
return IP2Location_get_record(loc, ip, COUNTRYLONG); |
|---|
| 141 |
} |
|---|
| 142 |
} |
|---|
| 143 |
|
|---|
| 144 |
|
|---|
| 145 |
IP2LocationRecord *IP2Location_get_region(IP2Location *loc, |
|---|
| 146 |
const char* ip) { |
|---|
| 147 |
if (loc->ipversion == IPV6) { |
|---|
| 148 |
return IP2Location_get_ipv6_record(loc, ip, REGION); |
|---|
| 149 |
} else { |
|---|
| 150 |
return IP2Location_get_record(loc, ip, REGION); |
|---|
| 151 |
} |
|---|
| 152 |
} |
|---|
| 153 |
|
|---|
| 154 |
|
|---|
| 155 |
IP2LocationRecord *IP2Location_get_city (IP2Location *loc, |
|---|
| 156 |
const char* ip) { |
|---|
| 157 |
if (loc->ipversion == IPV6) { |
|---|
| 158 |
return IP2Location_get_ipv6_record(loc, ip, CITY); |
|---|
| 159 |
} else { |
|---|
| 160 |
return IP2Location_get_record(loc, ip, CITY); |
|---|
| 161 |
} |
|---|
| 162 |
} |
|---|
| 163 |
|
|---|
| 164 |
|
|---|
| 165 |
IP2LocationRecord *IP2Location_get_isp(IP2Location *loc, |
|---|
| 166 |
const char* ip) { |
|---|
| 167 |
if (loc->ipversion == IPV6) { |
|---|
| 168 |
return IP2Location_get_ipv6_record(loc, ip, ISP); |
|---|
| 169 |
} else { |
|---|
| 170 |
return IP2Location_get_record(loc, ip, ISP); |
|---|
| 171 |
} |
|---|
| 172 |
} |
|---|
| 173 |
|
|---|
| 174 |
|
|---|
| 175 |
IP2LocationRecord *IP2Location_get_latitude(IP2Location *loc, |
|---|
| 176 |
const char* ip) { |
|---|
| 177 |
if (loc->ipversion == IPV6) { |
|---|
| 178 |
return IP2Location_get_ipv6_record(loc, ip, LATITUDE); |
|---|
| 179 |
} else { |
|---|
| 180 |
return IP2Location_get_record(loc, ip, LATITUDE); |
|---|
| 181 |
} |
|---|
| 182 |
} |
|---|
| 183 |
|
|---|
| 184 |
|
|---|
| 185 |
IP2LocationRecord *IP2Location_get_longitude(IP2Location *loc, |
|---|
| 186 |
const char* ip) { |
|---|
| 187 |
if (loc->ipversion == IPV6) { |
|---|
| 188 |
return IP2Location_get_ipv6_record(loc, ip, LONGITUDE); |
|---|
| 189 |
} else { |
|---|
| 190 |
return IP2Location_get_record(loc, ip, LONGITUDE); |
|---|
| 191 |
} |
|---|
| 192 |
} |
|---|
| 193 |
|
|---|
| 194 |
|
|---|
| 195 |
IP2LocationRecord *IP2Location_get_domain(IP2Location *loc, |
|---|
| 196 |
const char* ip) { |
|---|
| 197 |
if (loc->ipversion == IPV6) { |
|---|
| 198 |
return IP2Location_get_ipv6_record(loc, ip, DOMAIN); |
|---|
| 199 |
} else { |
|---|
| 200 |
return IP2Location_get_record(loc, ip, DOMAIN); |
|---|
| 201 |
} |
|---|
| 202 |
} |
|---|
| 203 |
|
|---|
| 204 |
|
|---|
| 205 |
IP2LocationRecord *IP2Location_get_zipcode(IP2Location *loc, |
|---|
| 206 |
const char* ip) { |
|---|
| 207 |
if (loc->ipversion == IPV6) { |
|---|
| 208 |
return IP2Location_get_ipv6_record(loc, ip, ZIPCODE); |
|---|
| 209 |
} else { |
|---|
| 210 |
return IP2Location_get_record(loc, ip, ZIPCODE); |
|---|
| 211 |
} |
|---|
| 212 |
} |
|---|
| 213 |
|
|---|
| 214 |
IP2LocationRecord *IP2Location_get_timezone(IP2Location *loc, |
|---|
| 215 |
const char* ip) { |
|---|
| 216 |
if (loc->ipversion == IPV6) { |
|---|
| 217 |
return IP2Location_get_ipv6_record(loc, ip, TIMEZONE); |
|---|
| 218 |
} else { |
|---|
| 219 |
return IP2Location_get_record(loc, ip, TIMEZONE); |
|---|
| 220 |
} |
|---|
| 221 |
} |
|---|
| 222 |
|
|---|
| 223 |
IP2LocationRecord *IP2Location_get_netspeed(IP2Location *loc, |
|---|
| 224 |
const char* ip) { |
|---|
| 225 |
if (loc->ipversion == IPV6) { |
|---|
| 226 |
return IP2Location_get_ipv6_record(loc, ip, NETSPEED); |
|---|
| 227 |
} else { |
|---|
| 228 |
return IP2Location_get_record(loc, ip, NETSPEED); |
|---|
| 229 |
} |
|---|
| 230 |
} |
|---|
| 231 |
|
|---|
| 232 |
IP2LocationRecord *IP2Location_get_all(IP2Location *loc, |
|---|
| 233 |
const char* ip) { |
|---|
| 234 |
if (loc->ipversion == IPV6) { |
|---|
| 235 |
return IP2Location_get_ipv6_record(loc, ip, ALL); |
|---|
| 236 |
} else { |
|---|
| 237 |
return IP2Location_get_record(loc, ip, ALL); |
|---|
| 238 |
} |
|---|
| 239 |
} |
|---|
| 240 |
|
|---|
| 241 |
IP2LocationRecord *IP2Location_get_ipv6_record(IP2Location *loc, |
|---|
| 242 |
const char* ipstring, |
|---|
| 243 |
uint32 mode) { |
|---|
| 244 |
uint8 dbtype = loc->databasetype; |
|---|
| 245 |
mpz ipno; |
|---|
| 246 |
FILE *handle = loc->filehandle; |
|---|
| 247 |
uint32 baseaddr = loc->databaseaddr; |
|---|
| 248 |
uint32 dbcount = loc->databasecount; |
|---|
| 249 |
uint32 dbcolumn = loc->databasecolumn; |
|---|
| 250 |
|
|---|
| 251 |
uint32 low = 0; |
|---|
| 252 |
uint32 high = dbcount; |
|---|
| 253 |
uint32 mid = 0; |
|---|
| 254 |
mpz ipfrom, ipto; |
|---|
| 255 |
IP2LocationRecord *record = IP2Location_new_record(); |
|---|
| 256 |
mp_int_init(&ipfrom); |
|---|
| 257 |
mp_int_init(&ipto); |
|---|
| 258 |
|
|---|
| 259 |
|
|---|
| 260 |
if(IP2Location_ip_is_ipv6(ipstring) == 0 ) { |
|---|
| 261 |
record->country_short = strdup(INVALID_IPV6_ADDRESS); |
|---|
| 262 |
record->country_long = strdup(INVALID_IPV6_ADDRESS); |
|---|
| 263 |
record->region = strdup(INVALID_IPV6_ADDRESS); |
|---|
| 264 |
record->city = strdup(INVALID_IPV6_ADDRESS); |
|---|
| 265 |
record->isp = strdup(INVALID_IPV6_ADDRESS); |
|---|
| 266 |
record->latitude = 0; |
|---|
| 267 |
record->longitude = 0; |
|---|
| 268 |
record->domain = strdup(INVALID_IPV6_ADDRESS); |
|---|
| 269 |
record->zipcode = strdup(INVALID_IPV6_ADDRESS); |
|---|
| 270 |
record->timezone = strdup(INVALID_IPV6_ADDRESS); |
|---|
| 271 |
record->netspeed = strdup(INVALID_IPV6_ADDRESS); |
|---|
| 272 |
return record; |
|---|
| 273 |
} |
|---|
| 274 |
|
|---|
| 275 |
ipno = IP2Location_ipv6_to_no(ipstring); |
|---|
| 276 |
|
|---|
| 277 |
while (low <= high) |
|---|
| 278 |
{ |
|---|
| 279 |
mid = (uint32)((low + high)/2); |
|---|
| 280 |
mp_int_read_string(&ipfrom, 10, IP2Location_read128(handle, baseaddr + mid * (dbcolumn * 4 + 12))); |
|---|
| 281 |
mp_int_read_string(&ipto, 10, IP2Location_read128(handle, baseaddr + (mid + 1) * (dbcolumn * 4 + 12))); |
|---|
| 282 |
|
|---|
| 283 |
if( (mp_int_compare(&ipno, &ipfrom) >= 0) && (mp_int_compare(&ipno, &ipto) < 0)) |
|---|
| 284 |
{ |
|---|
| 285 |
if ((mode & COUNTRYSHORT) && (COUNTRY_POSITION[dbtype] != 0)) { |
|---|
| 286 |
/* $ip, $baseaddr + $mid *($dbcolumn * 4 + 12) + 12 + 4 * */ |
|---|
| 287 |
record->country_short = IP2Location_readStr(handle, IP2Location_read32(handle, baseaddr + mid * (dbcolumn * 4 + 12) + 12 + 4 * (COUNTRY_POSITION[dbtype]-1))); |
|---|
| 288 |
} else { |
|---|
| 289 |
record->country_short = strdup(NOT_SUPPORTED); |
|---|
| 290 |
} |
|---|
| 291 |
|
|---|
| 292 |
if ((mode & COUNTRYLONG) && (COUNTRY_POSITION[dbtype] != 0)) { |
|---|
| 293 |
record->country_long = IP2Location_readStr(handle, IP2Location_read32(handle, baseaddr + mid * (dbcolumn * 4 + 12) + 12 + 4 * (COUNTRY_POSITION[dbtype]-1))+3); |
|---|
| 294 |
} else { |
|---|
| 295 |
record->country_long = strdup(NOT_SUPPORTED); |
|---|
| 296 |
} |
|---|
| 297 |
|
|---|
| 298 |
if ((mode & REGION) && (REGION_POSITION[dbtype] != 0)) { |
|---|
| 299 |
record->region = IP2Location_readStr(handle, IP2Location_read32(handle, baseaddr + mid * (dbcolumn * 4 + 12) + 12 + 4 * (REGION_POSITION[dbtype]-1))); |
|---|
| 300 |
} else { |
|---|
| 301 |
record->region = strdup(NOT_SUPPORTED); |
|---|
| 302 |
} |
|---|
| 303 |
|
|---|
| 304 |
if ((mode & CITY) && (CITY_POSITION[dbtype] != 0)) { |
|---|
| 305 |
record->city = IP2Location_readStr(handle, IP2Location_read32(handle, baseaddr + mid * (dbcolumn * 4 + 12) + 12 + 4 * (CITY_POSITION[dbtype]-1))); |
|---|
| 306 |
} else { |
|---|
| 307 |
record->city = strdup(NOT_SUPPORTED); |
|---|
| 308 |
} |
|---|
| 309 |
|
|---|
| 310 |
if ((mode & ISP) && (ISP_POSITION[dbtype] != 0)) { |
|---|
| 311 |
record->isp = IP2Location_readStr(handle, IP2Location_read32(handle, baseaddr + mid * (dbcolumn * 4 + 12) + 12 + 4 * (ISP_POSITION[dbtype]-1))); |
|---|
| 312 |
} else { |
|---|
| 313 |
record->isp = strdup(NOT_SUPPORTED); |
|---|
| 314 |
} |
|---|
| 315 |
|
|---|
| 316 |
if ((mode & LATITUDE) && (LATITUDE_POSITION[dbtype] != 0)) { |
|---|
| 317 |
record->latitude = IP2Location_readFloat(handle, baseaddr + mid * (dbcolumn * 4 + 12) + 12 + 4 * (LATITUDE_POSITION[dbtype]-1)); |
|---|
| 318 |
} else { |
|---|
| 319 |
record->latitude = 0.0; |
|---|
| 320 |
} |
|---|
| 321 |
|
|---|
| 322 |
if ((mode & LONGITUDE) && (LONGITUDE_POSITION[dbtype] != 0)) { |
|---|
| 323 |
record->longitude = IP2Location_readFloat(handle, baseaddr + mid * (dbcolumn * 4 + 12) + 12 + 4 * (LONGITUDE_POSITION[dbtype]-1)); |
|---|
| 324 |
} else { |
|---|
| 325 |
record->longitude = 0.0; |
|---|
| 326 |
} |
|---|
| 327 |
|
|---|
| 328 |
if ((mode & DOMAIN) && (DOMAIN_POSITION[dbtype] != 0)) { |
|---|
| 329 |
record->domain = IP2Location_readStr(handle, IP2Location_read32(handle, baseaddr + mid * (dbcolumn * 4 + 12) + 12 + 4 * (DOMAIN_POSITION[dbtype]-1))); |
|---|
| 330 |
} else { |
|---|
| 331 |
record->domain = strdup(NOT_SUPPORTED); |
|---|
| 332 |
} |
|---|
| 333 |
|
|---|
| 334 |
if ((mode & ZIPCODE) && (ZIPCODE_POSITION[dbtype] != 0)) { |
|---|
| 335 |
record->zipcode = IP2Location_readStr(handle, IP2Location_read32(handle, baseaddr + mid * (dbcolumn * 4 + 12) + 12 + 4 * (ZIPCODE_POSITION[dbtype]-1))); |
|---|
| 336 |
} else { |
|---|
| 337 |
record->zipcode = strdup(NOT_SUPPORTED); |
|---|
| 338 |
} |
|---|
| 339 |
|
|---|
| 340 |
if ((mode & TIMEZONE) && (TIMEZONE_POSITION[dbtype] != 0)) { |
|---|
| 341 |
record->timezone = IP2Location_readStr(handle, IP2Location_read32(handle, baseaddr + mid * (dbcolumn * 4 + 12) + 12 + 4 * (TIMEZONE_POSITION[dbtype]-1))); |
|---|
| 342 |
} else { |
|---|
| 343 |
record->timezone = strdup(NOT_SUPPORTED); |
|---|
| 344 |
} |
|---|
| 345 |
|
|---|
| 346 |
if ((mode & NETSPEED) && (NETSPEED_POSITION[dbtype] != 0)) { |
|---|
| 347 |
record->netspeed = IP2Location_readStr(handle, IP2Location_read32(handle, baseaddr + mid * (dbcolumn * 4 + 12) + 12 + 4 * (NETSPEED_POSITION[dbtype]-1))); |
|---|
| 348 |
} else { |
|---|
| 349 |
record->netspeed = strdup(NOT_SUPPORTED); |
|---|
| 350 |
} |
|---|
| 351 |
|
|---|
| 352 |
return record; |
|---|
| 353 |
} else { |
|---|
| 354 |
if ( mp_int_compare(&ipno, &ipfrom) < 0 ) { |
|---|
| 355 |
high = mid - 1; |
|---|
| 356 |
} else { |
|---|
| 357 |
low = mid + 1; |
|---|
| 358 |
} |
|---|
| 359 |
} |
|---|
| 360 |
} |
|---|
| 361 |
IP2Location_free_record(record); |
|---|
| 362 |
return NULL; |
|---|
| 363 |
} |
|---|
| 364 |
|
|---|
| 365 |
IP2LocationRecord *IP2Location_get_record(IP2Location *loc, |
|---|
| 366 |
const char* ipstring, |
|---|
| 367 |
uint32 mode) { |
|---|
| 368 |
uint8 dbtype = loc->databasetype; |
|---|
| 369 |
uint32 ipno = IP2Location_ip2no(ipstring); |
|---|
| 370 |
FILE *handle = loc->filehandle; |
|---|
| 371 |
uint32 baseaddr = loc->databaseaddr; |
|---|
| 372 |
uint32 dbcount = loc->databasecount; |
|---|
| 373 |
uint32 dbcolumn = loc->databasecolumn; |
|---|
| 374 |
|
|---|
| 375 |
uint32 low = 0; |
|---|
| 376 |
uint32 high = dbcount; |
|---|
| 377 |
uint32 mid = 0; |
|---|
| 378 |
uint32 ipfrom = 0; |
|---|
| 379 |
uint32 ipto = 0; |
|---|
| 380 |
|
|---|
| 381 |
IP2LocationRecord *record = IP2Location_new_record(); |
|---|
| 382 |
if (ipno == (uint32) MAX_IPV4_RANGE) { |
|---|
| 383 |
ipno = ipno - 1; |
|---|
| 384 |
} |
|---|
| 385 |
|
|---|
| 386 |
if(IP2Location_ip_is_ipv4(ipstring) == 0 ) { |
|---|
| 387 |
record->country_short = strdup(INVALID_IPV4_ADDRESS); |
|---|
| 388 |
record->country_long = strdup(INVALID_IPV4_ADDRESS); |
|---|
| 389 |
record->region = strdup(INVALID_IPV4_ADDRESS); |
|---|
| 390 |
record->city = strdup(INVALID_IPV4_ADDRESS); |
|---|
| 391 |
record->isp = strdup(INVALID_IPV4_ADDRESS); |
|---|
| 392 |
record->latitude = 0; |
|---|
| 393 |
record->longitude = 0; |
|---|
| 394 |
record->domain = strdup(INVALID_IPV4_ADDRESS); |
|---|
| 395 |
record->zipcode = strdup(INVALID_IPV4_ADDRESS); |
|---|
| 396 |
record->timezone = strdup(INVALID_IPV4_ADDRESS); |
|---|
| 397 |
record->netspeed = strdup(INVALID_IPV4_ADDRESS); |
|---|
| 398 |
return record; |
|---|
| 399 |
} |
|---|
| 400 |
|
|---|
| 401 |
while (low <= high) |
|---|
| 402 |
{ |
|---|
| 403 |
mid = (uint32)((low + high)/2); |
|---|
| 404 |
ipfrom = IP2Location_read32(handle, baseaddr + mid * dbcolumn * 4); |
|---|
| 405 |
ipto = IP2Location_read32(handle, baseaddr + (mid + 1) * dbcolumn * 4); |
|---|
| 406 |
|
|---|
| 407 |
if ((ipno >= ipfrom) && (ipno < ipto)) |
|---|
| 408 |
{ |
|---|
| 409 |
if ((mode & COUNTRYSHORT) && (COUNTRY_POSITION[dbtype] != 0)) { |
|---|
| 410 |
record->country_short = IP2Location_readStr(handle, IP2Location_read32(handle, baseaddr + (mid * dbcolumn * 4) + 4 * (COUNTRY_POSITION[dbtype]-1))); |
|---|
| 411 |
} else { |
|---|
| 412 |
record->country_short = strdup(NOT_SUPPORTED); |
|---|
| 413 |
} |
|---|
| 414 |
|
|---|
| 415 |
if ((mode & COUNTRYLONG) && (COUNTRY_POSITION[dbtype] != 0)) { |
|---|
| 416 |
record->country_long = IP2Location_readStr(handle, IP2Location_read32(handle, baseaddr + (mid * dbcolumn * 4) + 4 * (COUNTRY_POSITION[dbtype]-1))+3); |
|---|
| 417 |
} else { |
|---|
| 418 |
record->country_long = strdup(NOT_SUPPORTED); |
|---|
| 419 |
} |
|---|
| 420 |
|
|---|
| 421 |
if ((mode & REGION) && (REGION_POSITION[dbtype] != 0)) { |
|---|
| 422 |
record->region = IP2Location_readStr(handle, IP2Location_read32(handle, baseaddr + (mid * dbcolumn * 4) + 4 * (REGION_POSITION[dbtype]-1))); |
|---|
| 423 |
} else { |
|---|
| 424 |
record->region = strdup(NOT_SUPPORTED); |
|---|
| 425 |
} |
|---|
| 426 |
|
|---|
| 427 |
if ((mode & CITY) && (CITY_POSITION[dbtype] != 0)) { |
|---|
| 428 |
record->city = IP2Location_readStr(handle, IP2Location_read32(handle, baseaddr + (mid * dbcolumn * 4) + 4 * (CITY_POSITION[dbtype]-1))); |
|---|
| 429 |
} else { |
|---|
| 430 |
record->city = strdup(NOT_SUPPORTED); |
|---|
| 431 |
} |
|---|
| 432 |
|
|---|
| 433 |
if ((mode & ISP) && (ISP_POSITION[dbtype] != 0)) { |
|---|
| 434 |
record->isp = IP2Location_readStr(handle, IP2Location_read32(handle, baseaddr + (mid * dbcolumn * 4) + 4 * (ISP_POSITION[dbtype]-1))); |
|---|
| 435 |
} else { |
|---|
| 436 |
record->isp = strdup(NOT_SUPPORTED); |
|---|
| 437 |
} |
|---|
| 438 |
|
|---|
| 439 |
if ((mode & LATITUDE) && (LATITUDE_POSITION[dbtype] != 0)) { |
|---|
| 440 |
record->latitude = IP2Location_readFloat(handle, baseaddr + (mid * dbcolumn * 4) + 4 * (LATITUDE_POSITION[dbtype]-1)); |
|---|
| 441 |
} else { |
|---|
| 442 |
record->latitude = 0.0; |
|---|
| 443 |
} |
|---|
| 444 |
|
|---|
| 445 |
if ((mode & LONGITUDE) && (LONGITUDE_POSITION[dbtype] != 0)) { |
|---|
| 446 |
record->longitude = IP2Location_readFloat(handle, baseaddr + (mid * dbcolumn * 4) + 4 * (LONGITUDE_POSITION[dbtype]-1)); |
|---|
| 447 |
} else { |
|---|
| 448 |
record->longitude = 0.0; |
|---|
| 449 |
} |
|---|
| 450 |
|
|---|
| 451 |
if ((mode & DOMAIN) && (DOMAIN_POSITION[dbtype] != 0)) { |
|---|
| 452 |
record->domain = IP2Location_readStr(handle, IP2Location_read32(handle, baseaddr + (mid * dbcolumn * 4) + 4 * (DOMAIN_POSITION[dbtype]-1))); |
|---|
| 453 |
} else { |
|---|
| 454 |
record->domain = strdup(NOT_SUPPORTED); |
|---|
| 455 |
} |
|---|
| 456 |
|
|---|
| 457 |
if ((mode & ZIPCODE) && (ZIPCODE_POSITION[dbtype] != 0)) { |
|---|
| 458 |
record->zipcode = IP2Location_readStr(handle, IP2Location_read32(handle, baseaddr + (mid * dbcolumn * 4) + 4 * (ZIPCODE_POSITION[dbtype]-1))); |
|---|
| 459 |
} else { |
|---|
| 460 |
record->zipcode = strdup(NOT_SUPPORTED); |
|---|
| 461 |
} |
|---|
| 462 |
|
|---|
| 463 |
if ((mode & TIMEZONE) && (TIMEZONE_POSITION[dbtype] != 0)) { |
|---|
| 464 |
record->timezone = IP2Location_readStr(handle, IP2Location_read32(handle, baseaddr + (mid * dbcolumn * 4) + 4 * (TIMEZONE_POSITION[dbtype]-1))); |
|---|
| 465 |
} else { |
|---|
| 466 |
record->timezone = strdup(NOT_SUPPORTED); |
|---|
| 467 |
} |
|---|
| 468 |
|
|---|
| 469 |
if ((mode & NETSPEED) && (NETSPEED_POSITION[dbtype] != 0)) { |
|---|
| 470 |
record->netspeed = IP2Location_readStr(handle, IP2Location_read32(handle, baseaddr + (mid * dbcolumn * 4) + 4 * (NETSPEED_POSITION[dbtype]-1))); |
|---|
| 471 |
} else { |
|---|
| 472 |
record->netspeed = strdup(NOT_SUPPORTED); |
|---|
| 473 |
} |
|---|
| 474 |
|
|---|
| 475 |
return record; |
|---|
| 476 |
} else { |
|---|
| 477 |
if ( ipno < ipfrom ) { |
|---|
| 478 |
high = mid - 1; |
|---|
| 479 |
} else { |
|---|
| 480 |
low = mid + 1; |
|---|
| 481 |
} |
|---|
| 482 |
} |
|---|
| 483 |
} |
|---|
| 484 |
IP2Location_free_record(record); |
|---|
| 485 |
return NULL; |
|---|
| 486 |
} |
|---|
| 487 |
|
|---|
| 488 |
|
|---|
| 489 |
IP2LocationRecord *IP2Location_new_record() { |
|---|
| 490 |
IP2LocationRecord *record = (IP2LocationRecord *) malloc(sizeof(IP2LocationRecord)); |
|---|
| 491 |
memset(record, 0, sizeof(IP2LocationRecord)); |
|---|
| 492 |
return record; |
|---|
| 493 |
} |
|---|
| 494 |
|
|---|
| 495 |
|
|---|
| 496 |
void IP2Location_free_record(IP2LocationRecord *record) { |
|---|
| 497 |
if (record->city != NULL) |
|---|
| 498 |
free(record->city); |
|---|
| 499 |
|
|---|
| 500 |
if (record->country_long != NULL) |
|---|
| 501 |
free(record->country_long); |
|---|
| 502 |
|
|---|
| 503 |
if (record->country_short != NULL) |
|---|
| 504 |
free(record->country_short); |
|---|
| 505 |
|
|---|
| 506 |
if (record->domain != NULL) |
|---|
| 507 |
free(record->domain); |
|---|
| 508 |
|
|---|
| 509 |
if (record->isp != NULL) |
|---|
| 510 |
free(record->isp); |
|---|
| 511 |
|
|---|
| 512 |
if (record->region != NULL) |
|---|
| 513 |
free(record->region); |
|---|
| 514 |
|
|---|
| 515 |
if (record->zipcode != NULL) |
|---|
| 516 |
free(record->zipcode); |
|---|
| 517 |
|
|---|
| 518 |
if (record->timezone != NULL) |
|---|
| 519 |
free(record->timezone); |
|---|
| 520 |
|
|---|
| 521 |
if (record->netspeed != NULL) |
|---|
| 522 |
free(record->netspeed); |
|---|
| 523 |
|
|---|
| 524 |
free(record); |
|---|
| 525 |
} |
|---|
| 526 |
|
|---|
| 527 |
char* IP2Location_read128(FILE *handle, uint32 position) { |
|---|
| 528 |
uint32 b96_127 = IP2Location_read32(handle, position); |
|---|
| 529 |
uint32 b64_95 = IP2Location_read32(handle, position + 4); |
|---|
| 530 |
uint32 b32_63 = IP2Location_read32(handle, position + 8); |
|---|
| 531 |
uint32 b1_31 = IP2Location_read32(handle, position + 12); |
|---|
| 532 |
|
|---|
| 533 |
mpz result, multiplier, mp96_127, mp64_95, mp32_63, mp1_31; |
|---|
| 534 |
mp_int_init(&result); |
|---|
| 535 |
mp_int_init(&multiplier); |
|---|
| 536 |
mp_int_init(&mp96_127); |
|---|
| 537 |
mp_int_init(&mp64_95); |
|---|
| 538 |
mp_int_init(&mp32_63); |
|---|
| 539 |
mp_int_init(&mp1_31); |
|---|
| 540 |
|
|---|
| 541 |
mp_int_init_value(&multiplier, 65536); |
|---|
| 542 |
mp_int_mul(&multiplier, &multiplier, &multiplier); |
|---|
| 543 |
mp_int_init_value(&mp96_127, b96_127); |
|---|
| 544 |
mp_int_init_value(&mp64_95, b64_95); |
|---|
| 545 |
mp_int_init_value(&mp32_63, b32_63); |
|---|
| 546 |
mp_int_init_value(&mp1_31, b1_31); |
|---|
| 547 |
|
|---|
| 548 |
mp_int_mul(&mp1_31, &multiplier, &mp1_31); |
|---|
| 549 |
mp_int_mul(&mp1_31, &multiplier, &mp1_31); |
|---|
| 550 |
mp_int_mul(&mp1_31, &multiplier, &mp1_31); |
|---|
| 551 |
|
|---|
| 552 |
mp_int_mul(&mp32_63, &multiplier, &mp32_63); |
|---|
| 553 |
mp_int_mul(&mp32_63, &multiplier, &mp32_63); |
|---|
| 554 |
|
|---|
| 555 |
mp_int_mul(&mp64_95, &multiplier, &mp64_95); |
|---|
| 556 |
|
|---|
| 557 |
mp_int_add(&mp1_31, &mp32_63, &result); |
|---|
| 558 |
mp_int_add(&result, &mp64_95, &result); |
|---|
| 559 |
mp_int_add(&result, &mp96_127, &result); |
|---|
| 560 |
return IP2Location_mp2string(result); |
|---|
| 561 |
|
|---|
| 562 |
} |
|---|
| 563 |
|
|---|
| 564 |
uint32 IP2Location_read32(FILE *handle, uint32 position) { |
|---|
| 565 |
uint8 byte1 = 0; |
|---|
| 566 |
uint8 byte2 = 0; |
|---|
| 567 |
uint8 byte3 = 0; |
|---|
| 568 |
uint8 byte4 = 0; |
|---|
| 569 |
|
|---|
| 570 |
if (handle != NULL) { |
|---|
| 571 |
fseek(handle, position-1, 0); |
|---|
| 572 |
CHECK_EQ(1, fread(&byte1, 1, 1, handle)); |
|---|
| 573 |
CHECK_EQ(1, fread(&byte2, 1, 1, handle)); |
|---|
| 574 |
CHECK_EQ(1, fread(&byte3, 1, 1, handle)); |
|---|
| 575 |
CHECK_EQ(1, fread(&byte4, 1, 1, handle)); |
|---|
| 576 |
} |
|---|
| 577 |
return ((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | (byte1)); |
|---|
| 578 |
} |
|---|
| 579 |
|
|---|
| 580 |
uint8 IP2Location_read8(FILE *handle, uint32 position) { |
|---|
| 581 |
uint8 ret = 0; |
|---|
| 582 |
|
|---|
| 583 |
if (handle != NULL) { |
|---|
| 584 |
fseek(handle, position-1, 0); |
|---|
| 585 |
CHECK_EQ(1, fread(&ret, 1, 1, handle)); |
|---|
| 586 |
} |
|---|
| 587 |
return ret; |
|---|
| 588 |
} |
|---|
| 589 |
|
|---|
| 590 |
|
|---|
| 591 |
char *IP2Location_readStr(FILE *handle, uint32 position) { |
|---|
| 592 |
uint8 size = 0; |
|---|
| 593 |
char *str = 0; |
|---|
| 594 |
|
|---|
| 595 |
if (handle != NULL) { |
|---|
| 596 |
fseek(handle, position, 0); |
|---|
| 597 |
CHECK_EQ(1, fread(&size, 1, 1, handle)); |
|---|
| 598 |
str = (char *)malloc(size+1); |
|---|
| 599 |
memset(str, 0, size+1); |
|---|
| 600 |
CHECK_EQ(size, fread(str, size, 1, handle)); |
|---|
| 601 |
} |
|---|
| 602 |
return str; |
|---|
| 603 |
} |
|---|
| 604 |
|
|---|
| 605 |
|
|---|
| 606 |
float IP2Location_readFloat(FILE *handle, uint32 position) { |
|---|
| 607 |
float ret = 0.0; |
|---|
| 608 |
|
|---|
| 609 |
#ifdef _SUN_ |
|---|
| 610 |
char * p = (char *) &ret; |
|---|
| 611 |
|
|---|
| 612 |
/* for SUN SPARC, have to reverse the byte order */ |
|---|
| 613 |
if (handle != NULL) { |
|---|
| 614 |
fseek(handle, position-1, 0); |
|---|
| 615 |
CHECK_EQ(1, fread(p+3, 1, 1, handle)); |
|---|
| 616 |
CHECK_EQ(1, fread(p+2, 1, 1, handle)); |
|---|
| 617 |
CHECK_EQ(1, fread(p+1, 1, 1, handle)); |
|---|
| 618 |
CHECK_EQ(1, fread(p, 1, 1, handle)) |
|---|
| 619 |
} |
|---|
| 620 |
#else |
|---|
| 621 |
if (handle != NULL) { |
|---|
| 622 |
fseek(handle, position-1, 0); |
|---|
| 623 |
CHECK_EQ(4, fread(&ret, 4, 1, handle)); |
|---|
| 624 |
} |
|---|
| 625 |
#endif |
|---|
| 626 |
return ret; |
|---|
| 627 |
} |
|---|
| 628 |
|
|---|
| 629 |
|
|---|
| 630 |
uint32 IP2Location_ip2no(const char* ipstring) { |
|---|
| 631 |
uint32 ip = inet_addr(ipstring); |
|---|
| 632 |
uint8 *ptr = (uint8 *) &ip; |
|---|
| 633 |
uint32 a = 0; |
|---|
| 634 |
|
|---|
| 635 |
if (ipstring != NULL) { |
|---|
| 636 |
a = (uint8)(ptr[3]); |
|---|
| 637 |
a += (uint8)(ptr[2]) * 256; |
|---|
| 638 |
a += (uint8)(ptr[1]) * 256 * 256; |
|---|
| 639 |
a += (uint8)(ptr[0]) * 256 * 256 * 256; |
|---|
| 640 |
} |
|---|
| 641 |
return a; |
|---|
| 642 |
} |
|---|
| 643 |
|
|---|
| 644 |
char* IP2Location_mp2string (mpz mp) { |
|---|
| 645 |
mpz test = mp; |
|---|
| 646 |
char* result = reinterpret_cast<char*>(malloc(sizeof(char) * 128)); |
|---|
| 647 |
memset(result, 0, 128); |
|---|
| 648 |
mp_int_to_string(&mp, 10, result, 128); |
|---|
| 649 |
return result; |
|---|
| 650 |
} |
|---|
| 651 |
|
|---|
| 652 |
mpz IP2Location_ipv6_to_no(const char* ipaddr) { |
|---|
| 653 |
char expanded[8]; |
|---|
| 654 |
int padCount = 2; |
|---|
| 655 |
StringList* array = 0; |
|---|
| 656 |
StringList* iter = 0; |
|---|
| 657 |
unsigned int n = IP2Location_substr_count(":", ipaddr); |
|---|
| 658 |
mpz ipsub, mpResult; |
|---|
| 659 |
int subLoc = 8; |
|---|
| 660 |
char* expanded_allocated = NULL; |
|---|
| 661 |
|
|---|
| 662 |
mp_int_init(&ipsub); |
|---|
| 663 |
mp_int_init(&mpResult); |
|---|
| 664 |
memset(&expanded, 0, 8); |
|---|
| 665 |
if(n < 7) { |
|---|
| 666 |
expanded[0] = ':'; |
|---|
| 667 |
expanded[1] = ':'; |
|---|
| 668 |
while(n < 7) { |
|---|
| 669 |
expanded[padCount] = ':'; |
|---|
| 670 |
padCount++; |
|---|
| 671 |
n++; |
|---|
| 672 |
} |
|---|
| 673 |
expanded_allocated = IP2Location_replace("::", expanded, ipaddr); |
|---|
| 674 |
ipaddr = expanded_allocated; |
|---|
| 675 |
} |
|---|
| 676 |
|
|---|
| 677 |
array = IP2Location_split(":", ipaddr, DEFAULT, -1); |
|---|
| 678 |
iter = array; |
|---|
| 679 |
mp_int_init_value(&mpResult, 0); |
|---|
| 680 |
for(iter=array; iter!= 0; iter=iter->next ){ |
|---|
| 681 |
subLoc--; |
|---|
| 682 |
if(strcmp(iter->data, "") == 0) |
|---|
| 683 |
continue; |
|---|
| 684 |
|
|---|
| 685 |
mp_int_read_string(&ipsub, 16, iter->data); |
|---|
| 686 |
mp_int_mul_pow2(&ipsub, (16*subLoc), &ipsub); |
|---|
| 687 |
mp_int_add(&mpResult, &ipsub, &mpResult); |
|---|
| 688 |
} |
|---|
| 689 |
|
|---|
| 690 |
if ( expanded_allocated ) { |
|---|
| 691 |
free(expanded_allocated); |
|---|
| 692 |
} |
|---|
| 693 |
mp_int_clear(&ipsub); |
|---|
| 694 |
FreeStringList(array); |
|---|
| 695 |
return mpResult; |
|---|
| 696 |
} |
|---|
| 697 |
|
|---|
| 698 |
int IP2Location_ip_is_ipv4 (const char* ipaddr) { |
|---|
| 699 |
unsigned int p; |
|---|
| 700 |
StringList* iparray = 0; |
|---|
| 701 |
StringList* ipsub = 0; |
|---|
| 702 |
for(p=0; p<strlen(ipaddr); p++) { |
|---|
| 703 |
if( (ipaddr[p] >= '0' && ipaddr[p] <= '9') || |
|---|
| 704 |
ipaddr[p] == '.' ) |
|---|
| 705 |
continue; |
|---|
| 706 |
else |
|---|
| 707 |
return 0; |
|---|
| 708 |
} |
|---|
| 709 |
|
|---|
| 710 |
if(ipaddr[0] == '.' || ipaddr[strlen(ipaddr)-1] == '.') { |
|---|
| 711 |
return 0; |
|---|
| 712 |
} |
|---|
| 713 |
|
|---|
| 714 |
if( IP2Location_substr_count("::", ipaddr) > 0 ) { |
|---|
| 715 |
return 0; |
|---|
| 716 |
} |
|---|
| 717 |
|
|---|
| 718 |
iparray = IP2Location_split(".", ipaddr, DEFAULT, -1); |
|---|
| 719 |
if(StringListCount(iparray) != 4) { |
|---|
| 720 |
return 0; |
|---|
| 721 |
} |
|---|
| 722 |
|
|---|
| 723 |
for(ipsub = iparray; ipsub->next!=0; ipsub=ipsub->next) { |
|---|
| 724 |
if(atoi(ipsub->data) < 0 || atoi(ipsub->data) > 255) { |
|---|
| 725 |
return 0; |
|---|
| 726 |
} |
|---|
| 727 |
} |
|---|
| 728 |
FreeStringList(iparray); |
|---|
| 729 |
return 1; |
|---|
| 730 |
} |
|---|
| 731 |
|
|---|
| 732 |
int IP2Location_ip_is_ipv6 (const char* ipaddr) { |
|---|
| 733 |
unsigned int n = 0; |
|---|
| 734 |
unsigned int k = 0; |
|---|
| 735 |
unsigned int m = 0; |
|---|
| 736 |
unsigned int p = 0; |
|---|
| 737 |
unsigned int checkFlag = 0; |
|---|
| 738 |
StringList* ipv6array = 0; |
|---|
| 739 |
StringList* ipsub = 0; |
|---|
| 740 |
|
|---|
| 741 |
n = IP2Location_substr_count(":", ipaddr); |
|---|
| 742 |
if (n < 1 || n > 7) { |
|---|
| 743 |
return 0; |
|---|
| 744 |
} |
|---|
| 745 |
|
|---|
| 746 |
k = 0; |
|---|
| 747 |
ipv6array = IP2Location_split(":", ipaddr, DEFAULT, -1); |
|---|
| 748 |
for(ipsub = ipv6array; ipsub->next!=0; ipsub=ipsub->next) |
|---|
| 749 |
{ |
|---|
| 750 |
k++; |
|---|
| 751 |
if (strcmp(ipsub->data, "") == 0) { |
|---|
| 752 |
continue; |
|---|
| 753 |
} |
|---|
| 754 |
|
|---|
| 755 |
if(strlen(ipsub->data) > 4) { |
|---|
| 756 |
return 0; |
|---|
| 757 |
} |
|---|
| 758 |
|
|---|
| 759 |
checkFlag = 1; |
|---|
| 760 |
for(p=0; p<strlen(ipsub->data); p++) { |
|---|
| 761 |
if( (ipsub->data[p] >= '0' && ipsub->data[p] <= '9') || |
|---|
| 762 |
(ipsub->data[p] >= 'a' && ipsub->data[p] <= 'f') || |
|---|
| 763 |
(ipsub->data[p] >= 'A' && ipsub->data[p] <= 'F') ) |
|---|
| 764 |
continue; |
|---|
| 765 |
else |
|---|
| 766 |
checkFlag = 0; |
|---|
| 767 |
} |
|---|
| 768 |
|
|---|
| 769 |
if(checkFlag) |
|---|
| 770 |
continue; |
|---|
| 771 |
|
|---|
| 772 |
if (k == n+1) { |
|---|
| 773 |
if (IP2Location_ip_is_ipv4(ipsub->data)) { |
|---|
| 774 |
// here we know it is embeded ipv4, should retrieve data from ipv4 db, pending... |
|---|
| 775 |
// the result of this will not be valid, since all characters are treated and calculated |
|---|
| 776 |
// in hex based. |
|---|
| 777 |
// In addition, embeded ipv4 requires 96 '0' bits. We need to check this too. |
|---|
| 778 |
continue; |
|---|
| 779 |
} |
|---|
| 780 |
} |
|---|
| 781 |
return 0; |
|---|
| 782 |
} |
|---|
| 783 |
|
|---|
| 784 |
m = IP2Location_substr_count("::", ipaddr); |
|---|
| 785 |
if (m > 1 && n < 7) { |
|---|
| 786 |
return 0; |
|---|
| 787 |
} |
|---|
| 788 |
return 1; |
|---|
| 789 |
} |
|---|
| 790 |
|
|---|
| 791 |
StringList* IP2Location_split(const char* delimiters, |
|---|
| 792 |
const char* targetString, |
|---|
| 793 |
unsigned int flags, |
|---|
| 794 |
int limit) { |
|---|
| 795 |
StringList* tokenHead = 0; |
|---|
| 796 |
StringList* prevToken = 0; |
|---|
| 797 |
StringList* tokenStore = 0; |
|---|
| 798 |
char* targetCopy = reinterpret_cast<char*>( |
|---|
| 799 |
malloc(sizeof(char)*(strlen(targetString)+1))); |
|---|
| 800 |
const char* token = NULL; |
|---|
| 801 |
unsigned int match, i, j = 0; |
|---|
| 802 |
strcpy(targetCopy, targetString); |
|---|
| 803 |
|
|---|
| 804 |
token = targetCopy; |
|---|
| 805 |
match = 0; |
|---|
| 806 |
for(i=0; i<strlen(targetCopy); i++) { |
|---|
| 807 |
if(match) { |
|---|
| 808 |
match = 0; |
|---|
| 809 |
token = targetCopy+i; |
|---|
| 810 |
} |
|---|
| 811 |
|
|---|
| 812 |
for(j=0; j<strlen(delimiters); j++) { |
|---|
| 813 |
if(targetCopy[i] == delimiters[j]) { |
|---|
| 814 |
match = 1; |
|---|
| 815 |
targetCopy[i] = 0; |
|---|
| 816 |
break; |
|---|
| 817 |
} |
|---|
| 818 |
} |
|---|
| 819 |
|
|---|
| 820 |
if(!match && ((i+1)!=strlen(targetCopy))) |
|---|
| 821 |
continue; |
|---|
| 822 |
|
|---|
| 823 |
add: |
|---|
| 824 |
tokenStore = reinterpret_cast<StringList*>(malloc(sizeof(StringList))); |
|---|
| 825 |
tokenStore->data = reinterpret_cast<char*>( |
|---|
| 826 |
malloc(sizeof(char)*(strlen(token)+1))); |
|---|
| 827 |
tokenStore->next = 0; |
|---|
| 828 |
if(prevToken == 0) |
|---|
| 829 |
tokenHead = tokenStore; |
|---|
| 830 |
else |
|---|
| 831 |
prevToken->next = tokenStore; |
|---|
| 832 |
|
|---|
| 833 |
prevToken = tokenStore; |
|---|
| 834 |
strcpy(tokenStore->data, token); |
|---|
| 835 |
targetCopy[i] = delimiters[j]; |
|---|
| 836 |
|
|---|
| 837 |
if(match && ((i+1)==strlen(targetCopy))) |
|---|
| 838 |
{ |
|---|
| 839 |
token = targetString+strlen(targetString); |
|---|
| 840 |
match = 0; |
|---|
| 841 |
goto add; |
|---|
| 842 |
} |
|---|
| 843 |
} |
|---|
| 844 |
|
|---|
| 845 |
free(targetCopy); |
|---|
| 846 |
return tokenHead; |
|---|
| 847 |
} |
|---|
| 848 |
|
|---|
| 849 |
unsigned int IP2Location_substr_count(const char* substr, |
|---|
| 850 |
const char* targetString) { |
|---|
| 851 |
unsigned int count = 0; |
|---|
| 852 |
const char* caret = targetString; |
|---|
| 853 |
while( (caret = strstr(caret, substr)) != 0 ) { |
|---|
| 854 |
count++; |
|---|
| 855 |
caret = caret + strlen(substr); |
|---|
| 856 |
} |
|---|
| 857 |
return count; |
|---|
| 858 |
} |
|---|
| 859 |
|
|---|
| 860 |
char* IP2Location_replace(const char* substr, |
|---|
| 861 |
const char* replace, |
|---|
| 862 |
const char* targetString) { |
|---|
| 863 |
// estimate max possible replaced string length |
|---|
| 864 |
char* buff = reinterpret_cast<char*>( |
|---|
| 865 |
malloc(sizeof(char) * ( (int)(strlen(targetString)/strlen(substr) + 0.5) * |
|---|
| 866 |
strlen(replace)))); |
|---|
| 867 |
const char* headCaret = targetString; |
|---|
| 868 |
const char* endCaret = 0; |
|---|
| 869 |
buff[0] = 0; |
|---|
| 870 |
|
|---|
| 871 |
while( (endCaret = strstr(headCaret, substr)) != 0) { |
|---|
| 872 |
strncat(buff, headCaret, endCaret-headCaret); |
|---|
| 873 |
strcat(buff, replace); |
|---|
| 874 |
headCaret = endCaret + strlen(substr); |
|---|
| 875 |
} |
|---|
| 876 |
strcat(buff, headCaret); |
|---|
| 877 |
return buff; |
|---|
| 878 |
} |
|---|
| 879 |
|
|---|
| 880 |
void FreeStringList (StringList* toFree) { |
|---|
| 881 |
if(toFree != 0) { |
|---|
| 882 |
if(toFree->data != 0) |
|---|
| 883 |
free(toFree->data); |
|---|
| 884 |
FreeStringList(toFree->next); |
|---|
| 885 |
free(toFree); |
|---|
| 886 |
} |
|---|
| 887 |
} |
|---|
| 888 |
|
|---|
| 889 |
unsigned int StringListCount (StringList* toCount) { |
|---|
| 890 |
unsigned int count=0; |
|---|
| 891 |
while(toCount!=0) { |
|---|
| 892 |
count++; |
|---|
| 893 |
toCount = toCount->next; |
|---|
| 894 |
} |
|---|
| 895 |
return count; |
|---|
| 896 |
} |
|---|