Class: GeoIP
- Inherits:
-
Object
- Object
- GeoIP
- Defined in:
- lib/geoip.rb
Constant Summary collapse
- VERSION =
"0.8.4"
Instance Attribute Summary collapse
-
#databaseType ⇒ Object
readonly
Returns the value of attribute databaseType.
Instance Method Summary collapse
-
#asn(hostname) ⇒ Object
Search a ASN GeoIP database for the specified host, returning the AS number + description.
-
#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.
-
#isp(hostname) ⇒ Object
(also: #organization)
Search a ISP GeoIP database for the specified host, returning the ISP.
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)
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 467 468 469 470 471 472 473 474 475 |
# File 'lib/geoip.rb', line 431 def initialize(filename, flags = 0) @mutex = Mutex.new @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.respond_to?(:getbyte) ? @file.getbyte : @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.
425 426 427 |
# File 'lib/geoip.rb', line 425 def databaseType @databaseType end |
Instance Method Details
#asn(hostname) ⇒ Object
Search a ASN GeoIP database for the specified host, returning the AS number + description
hostname
is a String holding the host’s DNS name or numeric IP address. Return the AS number + description
Source: geolite.maxmind.com/download/geoip/database/asnum/GeoIPASNum.dat.gz
676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 |
# File 'lib/geoip.rb', line 676 def asn(hostname) ip = hostname if ip.kind_of?(String) && ip !~ /^[0-9.]*$/ # Lookup IP address, we were given a name ip = IPSocket.getaddress(hostname) ip = '0.0.0.0' if ip == '::1' end # Convert numeric IP address to an integer ipnum = iptonum(ip) if (@databaseType != GEOIP_ASNUM_EDITION) throw "Invalid GeoIP database type, can't look up ASN by IP" end pos = seek_record(ipnum); record = "" @mutex.synchronize { @file.seek(pos + (2*@record_length-1) * @databaseSegments[0]) record = @file.read(MAX_ASN_RECORD_LENGTH) } record = record.sub(/\000.*/n, '') if record =~ /^(AS\d+)\s(.*)$/ # AS####, Description return [$1, $2] end end |
#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)
621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 |
# File 'lib/geoip.rb', line 621 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) ip = '0.0.0.0' if ip == '::1' 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); return nil if pos == @databaseSegments[0] 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
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 |
# File 'lib/geoip.rb', line 489 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) ip = '0.0.0.0' if ip == '::1' 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
711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 |
# File 'lib/geoip.rb', line 711 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 |
#isp(hostname) ⇒ Object Also known as: organization
Search a ISP GeoIP database for the specified host, returning the ISP
hostname
is a String holding the host’s DNS name or numeric IP address. Return the ISP name
645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 |
# File 'lib/geoip.rb', line 645 def isp(hostname) ip = hostname if ip.kind_of?(String) && ip !~ /^[0-9.]*$/ # Lookup IP address, we were given a name ip = IPSocket.getaddress(hostname) ip = '0.0.0.0' if ip == '::1' end # Convert numeric IP address to an integer ipnum = iptonum(ip) if @databaseType != GEOIP_ISP_EDITION throw "Invalid GeoIP database type, can't look up Organization/ISP by IP" end pos = seek_record(ipnum); record = "" @mutex.synchronize { @file.seek(pos + (2*@record_length-1) * @databaseSegments[0]) record = @file.read(MAX_ORG_RECORD_LENGTH) } record = record.sub(/\000.*/n, '') record end |