Class: GeoIP
- Inherits:
-
Object
- Object
- GeoIP
- Defined in:
- lib/geoip.rb
Instance Attribute Summary collapse
-
#databaseType ⇒ Object
readonly
Returns the value of attribute databaseType.
Instance Method Summary collapse
-
#city(hostname) ⇒ Object
Search the GeoIP database for the specified host, returning city info.
-
#country(hostname) ⇒ Object
Search the GeoIP database for the specified host, returning country info.
-
#each ⇒ Object
Iterate through a GeoIP city database.
-
#initialize(filename, flags = 0) ⇒ GeoIP
constructor
Open the GeoIP database and determine the file format version.
Constructor Details
#initialize(filename, flags = 0) ⇒ GeoIP
Open the GeoIP database and determine the file format version
filename
is a String holding the path to the GeoIP.dat file options
is an integer holding caching flags (unimplemented)
423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 |
# File 'lib/geoip.rb', line 423 def initialize(filename, flags = 0) @flags = flags @databaseType = GEOIP_COUNTRY_EDITION @record_length = STANDARD_RECORD_LENGTH @file = File.open(filename, 'rb') @file.seek(-3, IO::SEEK_END) 0.upto(STRUCTURE_INFO_MAX_SIZE-1) { |i| if @file.read(3) == "\xFF\xFF\xFF" @databaseType = @file.getc @databaseType -= 105 if @databaseType >= 106 if (@databaseType == GEOIP_REGION_EDITION_REV0) # Region Edition, pre June 2003 @databaseSegments = [ STATE_BEGIN_REV0 ] elsif (@databaseType == GEOIP_REGION_EDITION_REV1) # Region Edition, post June 2003 @databaseSegments = [ STATE_BEGIN_REV1 ] elsif (@databaseType == GEOIP_CITY_EDITION_REV0 || @databaseType == GEOIP_CITY_EDITION_REV1 || @databaseType == GEOIP_ORG_EDITION || @databaseType == GEOIP_ISP_EDITION || @databaseType == GEOIP_ASNUM_EDITION) # City/Org Editions have two segments, read offset of second segment @databaseSegments = [ 0 ] sr = @file.read(3).unpack("C*") @databaseSegments[0] += le_to_ui(sr) if (@databaseType == GEOIP_ORG_EDITION || @databaseType == GEOIP_ISP_EDITION) @record_length = 4 end end break else @file.seek(-4, IO::SEEK_CUR) end } if (@databaseType == GEOIP_COUNTRY_EDITION || @databaseType == GEOIP_PROXY_EDITION || @databaseType == GEOIP_NETSPEED_EDITION) @databaseSegments = [ COUNTRY_BEGIN ] end end |
Instance Attribute Details
#databaseType ⇒ Object (readonly)
Returns the value of attribute databaseType.
418 419 420 |
# File 'lib/geoip.rb', line 418 def databaseType @databaseType end |
Instance Method Details
#city(hostname) ⇒ Object
Search the GeoIP database for the specified host, returning city info.
hostname
is a String holding the host’s DNS name or numeric IP address. Return an array of twelve or fourteen elements:
-
The host or IP address string as requested
-
The IP address string after looking up the host
-
The GeoIP country-ID as an integer
-
The ISO3166-1 two-character country code
-
The ISO3166-2 three-character country code
-
The ISO3166 English-language name of the country
-
The two-character continent code
-
The region name
-
The city name
-
The postal code
-
The latitude
-
The longitude
-
The USA dma_code and area_code, if available (REV1 City database)
607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 |
# File 'lib/geoip.rb', line 607 def city(hostname) ip = hostname if ip.kind_of?(String) && ip !~ /^[0-9.]*$/ # Lookup IP address, we were given a name ip = IPSocket.getaddress(hostname) end # Convert numeric IP address to an integer ipnum = iptonum(ip) if (@databaseType != GEOIP_CITY_EDITION_REV0 && @databaseType != GEOIP_CITY_EDITION_REV1) throw "Invalid GeoIP database type, can't look up City by IP" end pos = seek_record(ipnum); read_city(pos, hostname, ip) end |
#country(hostname) ⇒ Object
Search the GeoIP database for the specified host, returning country info
hostname
is a String holding the host’s DNS name or numeric IP address. Return an array of seven elements:
-
The host or IP address string as requested
-
The IP address string after looking up the host
-
The GeoIP country-ID as an integer
-
The ISO3166-1 two-character country code
-
The ISO3166-2 three-character country code
-
The ISO3166 English-language name of the country
-
The two-character continent code
480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 |
# File 'lib/geoip.rb', line 480 def country(hostname) if (@databaseType == GEOIP_CITY_EDITION_REV0 || @databaseType == GEOIP_CITY_EDITION_REV1) return city(hostname) end ip = hostname if ip.kind_of?(String) && ip !~ /^[0-9.]*$/ # Lookup IP address, we were given a name ip = IPSocket.getaddress(hostname) end # Convert numeric IP address to an integer ipnum = iptonum(ip) if (@databaseType != GEOIP_COUNTRY_EDITION && @databaseType != GEOIP_PROXY_EDITION && @databaseType != GEOIP_NETSPEED_EDITION) throw "Invalid GeoIP database type, can't look up Country by IP" end code = seek_record(ipnum) - COUNTRY_BEGIN; [ hostname, # Requested hostname ip, # Ip address as dotted quad code, # GeoIP's country code CountryCode[code], # ISO3166-1 code CountryCode3[code], # ISO3166-2 code CountryName[code], # Country name, per IS03166 CountryContinent[code] ] # Continent code. end |
#each ⇒ Object
Iterate through a GeoIP city database
625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 |
# File 'lib/geoip.rb', line 625 def each if (@databaseType != GEOIP_CITY_EDITION_REV0 && @databaseType != GEOIP_CITY_EDITION_REV1) throw "Invalid GeoIP database type, can't iterate thru non-City database" end @iter_pos = @databaseSegments[0] + 1 num = 0 until((rec = read_city(@iter_pos)).nil?) yield(rec) print "#{num}: #{@iter_pos}\n" if((num += 1) % 1000 == 0) end @iter_pos = nil self end |