Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.GeoIP/1.12/LookupService.cs @ 10262

Last change on this file since 10262 was 8040, checked in by ascheibe, 12 years ago

#1648 integrated server parts of the access service into trunk

File size: 23.9 KB
Line 
1/**
2 * LookupService.cs
3 *
4 * Copyright (C) 2008 MaxMind Inc.  All Rights Reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21
22using System;
23using System.IO;
24using System.Net;
25using System.Runtime.CompilerServices;
26
27public class LookupService {
28  private FileStream file = null;
29  private DatabaseInfo databaseInfo = null;
30  byte databaseType = Convert.ToByte(DatabaseInfo.COUNTRY_EDITION);
31  int[] databaseSegments;
32  int recordLength;
33  int dboptions;
34  byte[] dbbuffer;
35
36  String licenseKey;
37  int dnsService = 0;
38  private static Country UNKNOWN_COUNTRY = new Country("--", "N/A");
39  private static int COUNTRY_BEGIN = 16776960;
40  private static int STATE_BEGIN = 16700000;
41  private static int STRUCTURE_INFO_MAX_SIZE = 20;
42  private static int DATABASE_INFO_MAX_SIZE = 100;
43  private static int FULL_RECORD_LENGTH = 100;//???
44  private static int SEGMENT_RECORD_LENGTH = 3;
45  private static int STANDARD_RECORD_LENGTH = 3;
46  private static int ORG_RECORD_LENGTH = 4;
47  private static int MAX_RECORD_LENGTH = 4;
48  private static int MAX_ORG_RECORD_LENGTH = 1000;//???
49  private static int FIPS_RANGE = 360;
50  private static int STATE_BEGIN_REV0 = 16700000;
51  private static int STATE_BEGIN_REV1 = 16000000;
52  private static int US_OFFSET = 1;
53  private static int CANADA_OFFSET = 677;
54  private static int WORLD_OFFSET = 1353;
55  public static int GEOIP_STANDARD = 0;
56  public static int GEOIP_MEMORY_CACHE = 1;
57  public static int GEOIP_UNKNOWN_SPEED = 0;
58  public static int GEOIP_DIALUP_SPEED = 1;
59  public static int GEOIP_CABLEDSL_SPEED = 2;
60  public static int GEOIP_CORPORATE_SPEED = 3;
61
62  private static String[] countryCode = {
63        "--","AP","EU","AD","AE","AF","AG","AI","AL","AM","AN","AO","AQ","AR",
64        "AS","AT","AU","AW","AZ","BA","BB","BD","BE","BF","BG","BH","BI","BJ",
65        "BM","BN","BO","BR","BS","BT","BV","BW","BY","BZ","CA","CC","CD","CF",
66        "CG","CH","CI","CK","CL","CM","CN","CO","CR","CU","CV","CX","CY","CZ",
67        "DE","DJ","DK","DM","DO","DZ","EC","EE","EG","EH","ER","ES","ET","FI",
68        "FJ","FK","FM","FO","FR","FX","GA","GB","GD","GE","GF","GH","GI","GL",
69        "GM","GN","GP","GQ","GR","GS","GT","GU","GW","GY","HK","HM","HN","HR",
70        "HT","HU","ID","IE","IL","IN","IO","IQ","IR","IS","IT","JM","JO","JP",
71        "KE","KG","KH","KI","KM","KN","KP","KR","KW","KY","KZ","LA","LB","LC",
72        "LI","LK","LR","LS","LT","LU","LV","LY","MA","MC","MD","MG","MH","MK",
73        "ML","MM","MN","MO","MP","MQ","MR","MS","MT","MU","MV","MW","MX","MY",
74        "MZ","NA","NC","NE","NF","NG","NI","NL","NO","NP","NR","NU","NZ","OM",
75        "PA","PE","PF","PG","PH","PK","PL","PM","PN","PR","PS","PT","PW","PY",
76        "QA","RE","RO","RU","RW","SA","SB","SC","SD","SE","SG","SH","SI","SJ",
77        "SK","SL","SM","SN","SO","SR","ST","SV","SY","SZ","TC","TD","TF","TG",
78        "TH","TJ","TK","TM","TN","TO","TL","TR","TT","TV","TW","TZ","UA","UG",
79        "UM","US","UY","UZ","VA","VC","VE","VG","VI","VN","VU","WF","WS","YE",
80        "YT","RS","ZA","ZM","ME","ZW","A1","A2","O1","AX","GG","IM","JE","BL",
81  "MF"};
82
83  private static String[] countryName = {
84            "N/A","Asia/Pacific Region","Europe","Andorra","United Arab Emirates",
85            "Afghanistan","Antigua and Barbuda","Anguilla","Albania","Armenia",
86            "Netherlands Antilles","Angola","Antarctica","Argentina","American Samoa",
87            "Austria","Australia","Aruba","Azerbaijan","Bosnia and Herzegovina",
88            "Barbados","Bangladesh","Belgium","Burkina Faso","Bulgaria","Bahrain",
89            "Burundi","Benin","Bermuda","Brunei Darussalam","Bolivia","Brazil","Bahamas",
90            "Bhutan","Bouvet Island","Botswana","Belarus","Belize","Canada",
91            "Cocos (Keeling) Islands","Congo, The Democratic Republic of the",
92            "Central African Republic","Congo","Switzerland","Cote D'Ivoire",
93            "Cook Islands","Chile","Cameroon","China","Colombia","Costa Rica","Cuba",
94            "Cape Verde","Christmas Island","Cyprus","Czech Republic","Germany",
95            "Djibouti","Denmark","Dominica","Dominican Republic","Algeria","Ecuador",
96            "Estonia","Egypt","Western Sahara","Eritrea","Spain","Ethiopia","Finland",
97            "Fiji","Falkland Islands (Malvinas)","Micronesia, Federated States of",
98            "Faroe Islands","France","France, Metropolitan","Gabon","United Kingdom",
99            "Grenada","Georgia","French Guiana","Ghana","Gibraltar","Greenland","Gambia",
100            "Guinea","Guadeloupe","Equatorial Guinea","Greece",
101            "South Georgia and the South Sandwich Islands","Guatemala","Guam",
102            "Guinea-Bissau","Guyana","Hong Kong","Heard Island and McDonald Islands",
103            "Honduras","Croatia","Haiti","Hungary","Indonesia","Ireland","Israel","India",
104            "British Indian Ocean Territory","Iraq","Iran, Islamic Republic of",
105            "Iceland","Italy","Jamaica","Jordan","Japan","Kenya","Kyrgyzstan","Cambodia",
106            "Kiribati","Comoros","Saint Kitts and Nevis",
107            "Korea, Democratic People's Republic of","Korea, Republic of","Kuwait",
108            "Cayman Islands","Kazakhstan","Lao People's Democratic Republic","Lebanon",
109            "Saint Lucia","Liechtenstein","Sri Lanka","Liberia","Lesotho","Lithuania",
110            "Luxembourg","Latvia","Libyan Arab Jamahiriya","Morocco","Monaco",
111            "Moldova, Republic of","Madagascar","Marshall Islands",
112            "Macedonia, the Former Yugoslav Republic of","Mali","Myanmar","Mongolia",
113            "Macau","Northern Mariana Islands","Martinique","Mauritania","Montserrat",
114            "Malta","Mauritius","Maldives","Malawi","Mexico","Malaysia","Mozambique",
115            "Namibia","New Caledonia","Niger","Norfolk Island","Nigeria","Nicaragua",
116            "Netherlands","Norway","Nepal","Nauru","Niue","New Zealand","Oman","Panama",
117            "Peru","French Polynesia","Papua New Guinea","Philippines","Pakistan",
118            "Poland","Saint Pierre and Miquelon","Pitcairn","Puerto Rico","" +
119            "Palestinian Territory, Occupied","Portugal","Palau","Paraguay","Qatar",
120            "Reunion","Romania","Russian Federation","Rwanda","Saudi Arabia",
121            "Solomon Islands","Seychelles","Sudan","Sweden","Singapore","Saint Helena",
122            "Slovenia","Svalbard and Jan Mayen","Slovakia","Sierra Leone","San Marino",
123            "Senegal","Somalia","Suriname","Sao Tome and Principe","El Salvador",
124            "Syrian Arab Republic","Swaziland","Turks and Caicos Islands","Chad",
125            "French Southern Territories","Togo","Thailand","Tajikistan","Tokelau",
126            "Turkmenistan","Tunisia","Tonga","Timor-Leste","Turkey","Trinidad and Tobago",
127            "Tuvalu","Taiwan","Tanzania, United Republic of","Ukraine","Uganda",
128            "United States Minor Outlying Islands","United States","Uruguay","Uzbekistan",
129            "Holy See (Vatican City State)","Saint Vincent and the Grenadines",
130            "Venezuela","Virgin Islands, British","Virgin Islands, U.S.","Vietnam",
131            "Vanuatu","Wallis and Futuna","Samoa","Yemen","Mayotte","Serbia",
132            "South Africa","Zambia","Montenegro","Zimbabwe","Anonymous Proxy",
133            "Satellite Provider","Other",
134      "Aland Islands","Guernsey","Isle of Man","Jersey","Saint Barthelemy",
135      "Saint Martin"};
136
137  public LookupService(String databaseFile, int options) {
138    try {
139      this.file = new FileStream(databaseFile, FileMode.Open, FileAccess.Read);
140      dboptions = options;
141      init();
142    }
143    catch (System.SystemException) {
144      Console.Write("cannot open file " + databaseFile + "\n");
145    }
146  }
147
148  public LookupService(String databaseFile)
149    : this(databaseFile, GEOIP_STANDARD) {
150  }
151
152  private void init() {
153    int i, j;
154    byte[] delim = new byte[3];
155    byte[] buf = new byte[SEGMENT_RECORD_LENGTH];
156    databaseType = (byte)DatabaseInfo.COUNTRY_EDITION;
157    recordLength = STANDARD_RECORD_LENGTH;
158    //file.Seek(file.Length() - 3,SeekOrigin.Begin);
159    file.Seek(-3, SeekOrigin.End);
160    for (i = 0; i < STRUCTURE_INFO_MAX_SIZE; i++) {
161      file.Read(delim, 0, 3);
162      if (delim[0] == 255 && delim[1] == 255 && delim[2] == 255) {
163        databaseType = Convert.ToByte(file.ReadByte());
164        if (databaseType >= 106) {
165          // Backward compatibility with databases from April 2003 and earlier
166          databaseType -= 105;
167        }
168        // Determine the database type.
169        if (databaseType == DatabaseInfo.REGION_EDITION_REV0) {
170          databaseSegments = new int[1];
171          databaseSegments[0] = STATE_BEGIN_REV0;
172          recordLength = STANDARD_RECORD_LENGTH;
173        } else if (databaseType == DatabaseInfo.REGION_EDITION_REV1) {
174          databaseSegments = new int[1];
175          databaseSegments[0] = STATE_BEGIN_REV1;
176          recordLength = STANDARD_RECORD_LENGTH;
177        } else if (databaseType == DatabaseInfo.CITY_EDITION_REV0 ||
178                databaseType == DatabaseInfo.CITY_EDITION_REV1 ||
179                databaseType == DatabaseInfo.ORG_EDITION ||
180                databaseType == DatabaseInfo.ISP_EDITION ||
181                databaseType == DatabaseInfo.ASNUM_EDITION) {
182          databaseSegments = new int[1];
183          databaseSegments[0] = 0;
184          if (databaseType == DatabaseInfo.CITY_EDITION_REV0 ||
185              databaseType == DatabaseInfo.CITY_EDITION_REV1) {
186            recordLength = STANDARD_RECORD_LENGTH;
187          } else {
188            recordLength = ORG_RECORD_LENGTH;
189          }
190          file.Read(buf, 0, SEGMENT_RECORD_LENGTH);
191          for (j = 0; j < SEGMENT_RECORD_LENGTH; j++) {
192            databaseSegments[0] += (unsignedByteToInt(buf[j]) << (j * 8));
193          }
194        }
195        break;
196      } else {
197        //file.Seek(file.getFilePointer() - 4);
198        file.Seek(-4, SeekOrigin.Current);
199        //file.Seek(file.position-4,SeekOrigin.Begin);
200      }
201    }
202    if ((databaseType == DatabaseInfo.COUNTRY_EDITION) |
203        (databaseType == DatabaseInfo.PROXY_EDITION) |
204        (databaseType == DatabaseInfo.NETSPEED_EDITION)) {
205      databaseSegments = new int[1];
206      databaseSegments[0] = COUNTRY_BEGIN;
207      recordLength = STANDARD_RECORD_LENGTH;
208    }
209    if ((dboptions & GEOIP_MEMORY_CACHE) == 1) {
210      int l = (int)file.Length;
211      dbbuffer = new byte[l];
212      file.Seek(0, SeekOrigin.Begin);
213      file.Read(dbbuffer, 0, l);
214    }
215  }
216  public void close() {
217    try {
218      file.Close();
219      file = null;
220    }
221    catch (Exception) { }
222  }
223  public Country getCountry(IPAddress ipAddress) {
224    return getCountry(bytestoLong(ipAddress.GetAddressBytes()));
225  }
226  public Country getCountry(String ipAddress) {
227    IPAddress addr;
228    try {
229      addr = IPAddress.Parse(ipAddress);
230    }
231    //catch (UnknownHostException e) {
232    catch (Exception e) {
233      Console.Write(e.Message);
234      return UNKNOWN_COUNTRY;
235    }
236    //  return getCountry(bytestoLong(addr.GetAddressBytes()));
237    return getCountry(bytestoLong(addr.GetAddressBytes()));
238  }
239  public Country getCountry(long ipAddress) {
240    if (file == null) {
241      //throw new IllegalStateException("Database has been closed.");
242      throw new Exception("Database has been closed.");
243    }
244    if ((databaseType == DatabaseInfo.CITY_EDITION_REV1) |
245    (databaseType == DatabaseInfo.CITY_EDITION_REV0)) {
246      Location l = getLocation(ipAddress);
247      if (l == null) {
248        return UNKNOWN_COUNTRY;
249      } else {
250        return new Country(l.countryCode, l.countryName);
251      }
252    } else {
253      int ret = SeekCountry(ipAddress) - COUNTRY_BEGIN;
254      if (ret == 0) {
255        return UNKNOWN_COUNTRY;
256      } else {
257        return new Country(countryCode[ret], countryName[ret]);
258      }
259    }
260  }
261
262  public int getID(String ipAddress) {
263    IPAddress addr;
264    try {
265      addr = IPAddress.Parse(ipAddress);
266    }
267    catch (Exception e) {
268      Console.Write(e.Message);
269      return 0;
270    }
271    return getID(bytestoLong(addr.GetAddressBytes()));
272  }
273
274  public int getID(IPAddress ipAddress) {
275
276    return getID(bytestoLong(ipAddress.GetAddressBytes()));
277  }
278
279  public int getID(long ipAddress) {
280    if (file == null) {
281      throw new Exception("Database has been closed.");
282    }
283    int ret = SeekCountry(ipAddress) - databaseSegments[0];
284    return ret;
285  }
286  public DatabaseInfo getDatabaseInfo() {
287    if (databaseInfo != null) {
288      return databaseInfo;
289    }
290    try {
291      // Synchronize since we're accessing the database file.
292      lock (this) {
293        bool hasStructureInfo = false;
294        byte[] delim = new byte[3];
295        // Advance to part of file where database info is stored.
296        file.Seek(-3, SeekOrigin.End);
297        for (int i = 0; i < STRUCTURE_INFO_MAX_SIZE; i++) {
298          file.Read(delim, 0, 3);
299          if (delim[0] == 255 && delim[1] == 255 && delim[2] == 255) {
300            hasStructureInfo = true;
301            break;
302          }
303        }
304        if (hasStructureInfo) {
305          file.Seek(-3, SeekOrigin.Current);
306        } else {
307          // No structure info, must be pre Sep 2002 database, go back to end.
308          file.Seek(-3, SeekOrigin.End);
309        }
310        // Find the database info string.
311        for (int i = 0; i < DATABASE_INFO_MAX_SIZE; i++) {
312          file.Read(delim, 0, 3);
313          if (delim[0] == 0 && delim[1] == 0 && delim[2] == 0) {
314            byte[] dbInfo = new byte[i];
315            char[] dbInfo2 = new char[i];
316            file.Read(dbInfo, 0, i);
317            for (int a0 = 0; a0 < i; a0++) {
318              dbInfo2[a0] = Convert.ToChar(dbInfo[a0]);
319            }
320            // Create the database info object using the string.
321            this.databaseInfo = new DatabaseInfo(new String(dbInfo2));
322            return databaseInfo;
323          }
324          file.Seek(-4, SeekOrigin.Current);
325        }
326      }
327    }
328    catch (Exception e) {
329      Console.Write(e.Message);
330      //e.printStackTrace();
331    }
332    return new DatabaseInfo("");
333  }
334  public Region getRegion(IPAddress ipAddress) {
335    return getRegion(bytestoLong(ipAddress.GetAddressBytes()));
336  }
337  public Region getRegion(String str) {
338    IPAddress addr;
339    try {
340      addr = IPAddress.Parse(str);
341    }
342    catch (Exception e) {
343      Console.Write(e.Message);
344      return null;
345    }
346
347    return getRegion(bytestoLong(addr.GetAddressBytes()));
348  }
349
350  [MethodImpl(MethodImplOptions.Synchronized)]
351  public Region getRegion(long ipnum) {
352    Region record = new Region();
353    int seek_region = 0;
354    if (databaseType == DatabaseInfo.REGION_EDITION_REV0) {
355      seek_region = SeekCountry(ipnum) - STATE_BEGIN_REV0;
356      char[] ch = new char[2];
357      if (seek_region >= 1000) {
358        record.countryCode = "US";
359        record.countryName = "United States";
360        ch[0] = (char)(((seek_region - 1000) / 26) + 65);
361        ch[1] = (char)(((seek_region - 1000) % 26) + 65);
362        record.region = new String(ch);
363      } else {
364        record.countryCode = countryCode[seek_region];
365        record.countryName = countryName[seek_region];
366        record.region = "";
367      }
368    } else if (databaseType == DatabaseInfo.REGION_EDITION_REV1) {
369      seek_region = SeekCountry(ipnum) - STATE_BEGIN_REV1;
370      char[] ch = new char[2];
371      if (seek_region < US_OFFSET) {
372        record.countryCode = "";
373        record.countryName = "";
374        record.region = "";
375      } else if (seek_region < CANADA_OFFSET) {
376        record.countryCode = "US";
377        record.countryName = "United States";
378        ch[0] = (char)(((seek_region - US_OFFSET) / 26) + 65);
379        ch[1] = (char)(((seek_region - US_OFFSET) % 26) + 65);
380        record.region = new String(ch);
381      } else if (seek_region < WORLD_OFFSET) {
382        record.countryCode = "CA";
383        record.countryName = "Canada";
384        ch[0] = (char)(((seek_region - CANADA_OFFSET) / 26) + 65);
385        ch[1] = (char)(((seek_region - CANADA_OFFSET) % 26) + 65);
386        record.region = new String(ch);
387      } else {
388        record.countryCode = countryCode[(seek_region - WORLD_OFFSET) / FIPS_RANGE];
389        record.countryName = countryName[(seek_region - WORLD_OFFSET) / FIPS_RANGE];
390        record.region = "";
391      }
392    }
393    return record;
394  }
395  public Location getLocation(IPAddress addr) {
396    return getLocation(bytestoLong(addr.GetAddressBytes()));
397  }
398  public Location getLocation(String str) {
399    IPAddress addr;
400    try {
401      addr = IPAddress.Parse(str);
402    }
403    catch (Exception e) {
404      Console.Write(e.Message);
405      return null;
406    }
407
408    return getLocation(bytestoLong(addr.GetAddressBytes()));
409  }
410
411  [MethodImpl(MethodImplOptions.Synchronized)]
412  public Location getLocation(long ipnum) {
413    int record_pointer;
414    byte[] record_buf = new byte[FULL_RECORD_LENGTH];
415    char[] record_buf2 = new char[FULL_RECORD_LENGTH];
416    int record_buf_offset = 0;
417    Location record = new Location();
418    int str_length = 0;
419    int j, Seek_country;
420    double latitude = 0, longitude = 0;
421
422    try {
423      Seek_country = SeekCountry(ipnum);
424      if (Seek_country == databaseSegments[0]) {
425        return null;
426      }
427      record_pointer = Seek_country + ((2 * recordLength - 1) * databaseSegments[0]);
428      if ((dboptions & GEOIP_MEMORY_CACHE) == 1) {
429        Array.Copy(dbbuffer, record_pointer, record_buf, 0, Math.Min(dbbuffer.Length - record_pointer, FULL_RECORD_LENGTH));
430      } else {
431        file.Seek(record_pointer, SeekOrigin.Begin);
432        file.Read(record_buf, 0, FULL_RECORD_LENGTH);
433      }
434      for (int a0 = 0; a0 < FULL_RECORD_LENGTH; a0++) {
435        record_buf2[a0] = Convert.ToChar(record_buf[a0]);
436      }
437      // get country
438      record.countryCode = countryCode[unsignedByteToInt(record_buf[0])];
439      record.countryName = countryName[unsignedByteToInt(record_buf[0])];
440      record_buf_offset++;
441
442      // get region
443      while (record_buf[record_buf_offset + str_length] != '\0')
444        str_length++;
445      if (str_length > 0) {
446        record.region = new String(record_buf2, record_buf_offset, str_length);
447      }
448      record_buf_offset += str_length + 1;
449      str_length = 0;
450
451      // get region_name
452      record.regionName = RegionName.getRegionName(record.countryCode, record.region);
453
454      // get city
455      while (record_buf[record_buf_offset + str_length] != '\0')
456        str_length++;
457      if (str_length > 0) {
458        record.city = new String(record_buf2, record_buf_offset, str_length);
459      }
460      record_buf_offset += (str_length + 1);
461      str_length = 0;
462
463      // get postal code
464      while (record_buf[record_buf_offset + str_length] != '\0')
465        str_length++;
466      if (str_length > 0) {
467        record.postalCode = new String(record_buf2, record_buf_offset, str_length);
468      }
469      record_buf_offset += (str_length + 1);
470
471      // get latitude
472      for (j = 0; j < 3; j++)
473        latitude += (unsignedByteToInt(record_buf[record_buf_offset + j]) << (j * 8));
474      record.latitude = (float)latitude / 10000 - 180;
475      record_buf_offset += 3;
476
477      // get longitude
478      for (j = 0; j < 3; j++)
479        longitude += (unsignedByteToInt(record_buf[record_buf_offset + j]) << (j * 8));
480      record.longitude = (float)longitude / 10000 - 180;
481
482      record.metro_code = record.dma_code = 0;
483      record.area_code = 0;
484      if (databaseType == DatabaseInfo.CITY_EDITION_REV1) {
485        // get metro_code
486        int metroarea_combo = 0;
487        if (record.countryCode == "US") {
488          record_buf_offset += 3;
489          for (j = 0; j < 3; j++)
490            metroarea_combo += (unsignedByteToInt(record_buf[record_buf_offset + j]) << (j * 8));
491          record.metro_code = record.dma_code = metroarea_combo / 1000;
492          record.area_code = metroarea_combo % 1000;
493        }
494      }
495    }
496    catch (IOException) {
497      Console.Write("IO Exception while seting up segments");
498    }
499    return record;
500  }
501  public String getOrg(IPAddress addr) {
502    return getOrg(bytestoLong(addr.GetAddressBytes()));
503  }
504  public String getOrg(String str) {
505    IPAddress addr;
506    try {
507      addr = IPAddress.Parse(str);
508    }
509    //catch (UnknownHostException e) {
510    catch (Exception e) {
511      Console.Write(e.Message);
512      return null;
513    }
514    return getOrg(bytestoLong(addr.GetAddressBytes()));
515  }
516
517  [MethodImpl(MethodImplOptions.Synchronized)]
518  public String getOrg(long ipnum) {
519    int Seek_org;
520    int record_pointer;
521    int str_length = 0;
522    byte[] buf = new byte[MAX_ORG_RECORD_LENGTH];
523    char[] buf2 = new char[MAX_ORG_RECORD_LENGTH];
524    String org_buf;
525
526    try {
527      Seek_org = SeekCountry(ipnum);
528      if (Seek_org == databaseSegments[0]) {
529        return null;
530      }
531
532      record_pointer = Seek_org + (2 * recordLength - 1) * databaseSegments[0];
533      if ((dboptions & GEOIP_MEMORY_CACHE) == 1) {
534        Array.Copy(dbbuffer, record_pointer, buf, 0, Math.Min(dbbuffer.Length - record_pointer, MAX_ORG_RECORD_LENGTH));
535      } else {
536        file.Seek(record_pointer, SeekOrigin.Begin);
537        file.Read(buf, 0, MAX_ORG_RECORD_LENGTH);
538      }
539      while (buf[str_length] != 0) {
540        buf2[str_length] = Convert.ToChar(buf[str_length]);
541        str_length++;
542      }
543      buf2[str_length] = '\0';
544      org_buf = new String(buf2, 0, str_length);
545      return org_buf;
546    }
547    catch (IOException) {
548      Console.Write("IO Exception");
549      return null;
550    }
551  }
552
553  [MethodImpl(MethodImplOptions.Synchronized)]
554  private int SeekCountry(long ipAddress) {
555    byte[] buf = new byte[2 * MAX_RECORD_LENGTH];
556    int[] x = new int[2];
557    int offset = 0;
558    for (int depth = 31; depth >= 0; depth--) {
559      try {
560        if ((dboptions & GEOIP_MEMORY_CACHE) == 1) {
561          for (int i = 0; i < (2 * MAX_RECORD_LENGTH); i++) {
562            buf[i] = dbbuffer[i + (2 * recordLength * offset)];
563          }
564        } else {
565          file.Seek(2 * recordLength * offset, SeekOrigin.Begin);
566          file.Read(buf, 0, 2 * MAX_RECORD_LENGTH);
567        }
568      }
569      catch (IOException) {
570        Console.Write("IO Exception");
571      }
572      for (int i = 0; i < 2; i++) {
573        x[i] = 0;
574        for (int j = 0; j < recordLength; j++) {
575          int y = buf[(i * recordLength) + j];
576          if (y < 0) {
577            y += 256;
578          }
579          x[i] += (y << (j * 8));
580        }
581      }
582
583      if ((ipAddress & (1 << depth)) > 0) {
584        if (x[1] >= databaseSegments[0]) {
585          return x[1];
586        }
587        offset = x[1];
588      } else {
589        if (x[0] >= databaseSegments[0]) {
590          return x[0];
591        }
592        offset = x[0];
593      }
594    }
595
596    // shouldn't reach here
597    Console.Write("Error Seeking country while Seeking " + ipAddress);
598    return 0;
599
600  }
601  private static long swapbytes(long ipAddress) {
602    return (((ipAddress >> 0) & 255) << 24) | (((ipAddress >> 8) & 255) << 16)
603| (((ipAddress >> 16) & 255) << 8) | (((ipAddress >> 24) & 255) << 0);
604  }
605  private static long bytestoLong(byte[] address) {
606    long ipnum = 0;
607    for (int i = 0; i < 4; ++i) {
608      long y = address[i];
609      if (y < 0) {
610        y += 256;
611      }
612      ipnum += y << ((3 - i) * 8);
613    }
614    return ipnum;
615  }
616  private static int unsignedByteToInt(byte b) {
617    return (int)b & 0xFF;
618  }
619
620}
Note: See TracBrowser for help on using the repository browser.