geoip 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/geoip.rb +86 -4
- metadata +6 -6
data/lib/geoip.rb
CHANGED
@@ -189,6 +189,7 @@ class GeoIP
|
|
189
189
|
CANADA_OFFSET = 677
|
190
190
|
WORLD_OFFSET = 1353
|
191
191
|
FIPS_RANGE = 360
|
192
|
+
FULL_RECORD_LENGTH = 50
|
192
193
|
|
193
194
|
STANDARD_RECORD_LENGTH = 3
|
194
195
|
SEGMENT_RECORD_LENGTH = 3
|
@@ -203,13 +204,15 @@ class GeoIP
|
|
203
204
|
@databaseType = GEOIP_COUNTRY_EDITION
|
204
205
|
@record_length = STANDARD_RECORD_LENGTH
|
205
206
|
@file = File.open(filename, 'rb')
|
206
|
-
@file.seek(-
|
207
|
-
|
207
|
+
@file.seek(-3, IO::SEEK_END)
|
208
|
+
0.upto(STRUCTURE_INFO_MAX_SIZE-1) { |i|
|
208
209
|
if @file.read(3) == "\xFF\xFF\xFF"
|
209
210
|
@databaseType = @file.getc
|
210
211
|
@databaseType -= 105 if @databaseType >= 106
|
211
212
|
|
212
|
-
|
213
|
+
if (@databaseType != GEOIP_CITY_EDITION_REV0)
|
214
|
+
puts "Old database file type #{@databaseType}, untested"
|
215
|
+
end
|
213
216
|
|
214
217
|
if (@databaseType == GEOIP_REGION_EDITION_REV0)
|
215
218
|
# Region Edition, pre June 2003
|
@@ -232,9 +235,10 @@ class GeoIP
|
|
232
235
|
@record_length = 4
|
233
236
|
end
|
234
237
|
end
|
238
|
+
break
|
235
239
|
|
236
240
|
else
|
237
|
-
@file.seek(-
|
241
|
+
@file.seek(-4, IO::SEEK_CUR)
|
238
242
|
end
|
239
243
|
}
|
240
244
|
if (@databaseType == GEOIP_COUNTRY_EDITION ||
|
@@ -257,6 +261,11 @@ class GeoIP
|
|
257
261
|
# * The two-character continent code
|
258
262
|
#
|
259
263
|
def country(hostname)
|
264
|
+
if (@databaseType == GEOIP_CITY_EDITION_REV0 ||
|
265
|
+
@databaseType == GEOIP_CITY_EDITION_REV1)
|
266
|
+
return city(hostname)
|
267
|
+
end
|
268
|
+
|
260
269
|
ip = hostname
|
261
270
|
if ip.kind_of?(String) && ip !~ /^[0-9.]*$/
|
262
271
|
# Lookup IP address, we were given a name
|
@@ -280,6 +289,79 @@ class GeoIP
|
|
280
289
|
CountryContinent[code] ] # Continent code.
|
281
290
|
end
|
282
291
|
|
292
|
+
# Search the GeoIP database for the specified host, returning city info
|
293
|
+
#
|
294
|
+
# +hostname+ is a String holding the host's DNS name or numeric IP address
|
295
|
+
# Return an array of eleven or thirteen elements:
|
296
|
+
# * All elements from the country query
|
297
|
+
# * The region (state or territory) name
|
298
|
+
# * The city name
|
299
|
+
# * The postal code (zipcode)
|
300
|
+
# * The latitude
|
301
|
+
# * The longitude
|
302
|
+
# * The dma_code and area_code, if available (REV1 City database)
|
303
|
+
def city(hostname)
|
304
|
+
ip = hostname
|
305
|
+
if ip.kind_of?(String) && ip !~ /^[0-9.]*$/
|
306
|
+
# Lookup IP address, we were given a name
|
307
|
+
ip = IPSocket.getaddress(hostname)
|
308
|
+
end
|
309
|
+
|
310
|
+
# Convert numeric IP address to an integer
|
311
|
+
ipnum = iptonum(ip)
|
312
|
+
if (@databaseType != GEOIP_CITY_EDITION_REV0 &&
|
313
|
+
@databaseType != GEOIP_CITY_EDITION_REV1)
|
314
|
+
throw "Invalid GeoIP database type, can't look up City by IP"
|
315
|
+
end
|
316
|
+
pos = seek_record(ipnum);
|
317
|
+
@file.seek(pos + (2*@record_length-1) * @databaseSegments[0])
|
318
|
+
record = @file.read(FULL_RECORD_LENGTH)
|
319
|
+
|
320
|
+
# The country code is the first byte:
|
321
|
+
code = record[0]
|
322
|
+
record = record[1..-1]
|
323
|
+
|
324
|
+
# Get the region:
|
325
|
+
region = record.sub(/\x00.*/, "")
|
326
|
+
record.sub!(/[^\x00]*\x00/, '')
|
327
|
+
|
328
|
+
# Get the city:
|
329
|
+
city = record.sub(/\x00.*/, "")
|
330
|
+
record.sub!(/[^\x00]*\x00/, '')
|
331
|
+
|
332
|
+
# Get the postal code:
|
333
|
+
postal_code = record.sub(/\x00.*/, "")
|
334
|
+
record.sub!(/[^\x00]*\x00/, '')
|
335
|
+
|
336
|
+
# Get the latitude/longitude:
|
337
|
+
latitude = le_to_ui(record[0,3].unpack("C*"))/10000.0 - 180
|
338
|
+
longitude = le_to_ui(record[3,3].unpack("C*"))/10000.0 - 180
|
339
|
+
|
340
|
+
record = record[6..-1]
|
341
|
+
us_area_codes = []
|
342
|
+
if (@databaseType == GEOIP_CITY_EDITION_REV1 &&
|
343
|
+
CountryCode[code] == "US") # UNTESTED
|
344
|
+
dmaarea_combo = le_to_ui(record[0,3].unpack("C*"))
|
345
|
+
dma_code = dmaarea_combo/1000;
|
346
|
+
area_code = dmaarea_combo%1000;
|
347
|
+
us_area_codes = [ dma_code, area_code ]
|
348
|
+
end
|
349
|
+
|
350
|
+
[ hostname, # Requested hostname
|
351
|
+
ip, # Ip address as dotted quad
|
352
|
+
CountryCode[code], # ISO3166-1 code
|
353
|
+
CountryCode3[code], # ISO3166-2 code
|
354
|
+
CountryName[code], # Country name, per IS03166
|
355
|
+
CountryContinent[code], # Continent code.
|
356
|
+
region, # Region name
|
357
|
+
city, # City name
|
358
|
+
postal_code, # Postal code
|
359
|
+
latitude,
|
360
|
+
longitude,
|
361
|
+
] + us_area_codes
|
362
|
+
|
363
|
+
end
|
364
|
+
|
283
365
|
private
|
284
366
|
def iptonum(ip) # Convert numeric IP address to integer
|
285
367
|
if ip.kind_of?(String) &&
|
metadata
CHANGED
@@ -3,13 +3,13 @@ rubygems_version: 0.8.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: geoip
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2005-
|
6
|
+
version: 0.2.0
|
7
|
+
date: 2005-04-27
|
8
8
|
summary: "GeoIP looks up a GeoIP database to provide geographical data for an IP address
|
9
9
|
or Internet hostname. The free version of the GeoIP database available from
|
10
|
-
www.maxmind.com only contains country information
|
11
|
-
|
12
|
-
codes at the end of the hosts' domain names."
|
10
|
+
www.maxmind.com only contains country information. This library supports that
|
11
|
+
and the GeoIPCity file (both revisions). The data is much more reliable than
|
12
|
+
using the country codes at the end of the hosts' domain names."
|
13
13
|
require_paths:
|
14
14
|
- lib
|
15
15
|
email: cjh@polyplex.org
|
@@ -40,5 +40,5 @@ extra_rdoc_files: []
|
|
40
40
|
executables: []
|
41
41
|
extensions: []
|
42
42
|
requirements:
|
43
|
-
- The free GeoIP database from www.maxmind.com
|
43
|
+
- The free GeoIP database or a GeoIP city database from www.maxmind.com
|
44
44
|
dependencies: []
|