root/trunk/whisperlib/net/util/third-party/IP2Location.cc

Revision 7, 27.3 kB (checked in by whispercastorg, 2 years ago)

version 0.2.0

  • Property svn:executable set to
Line 
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 }
Note: See TracBrowser for help on using the browser.