mirror of
https://github.com/certbot/certbot.git
synced 2026-07-28 08:45:22 +02:00
Merge branch 'master' of github.com:research/chocolate
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
[submodule "m3crypto"]
|
||||
path = m3crypto
|
||||
url = git@github.com:research/m3crypto.git
|
||||
[submodule "pygeoip"]
|
||||
path = pygeoip
|
||||
url = https://github.com/appliedsec/pygeoip.git
|
||||
|
||||
Submodule
+1
Submodule pygeoip added at 2bd928e6b3
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import pygeoip
|
||||
geoip = pygeoip.GeoIP('GeoIP.dat', pygeoip.MEMORY_CACHE)
|
||||
|
||||
allrouters = []
|
||||
exits = []
|
||||
|
||||
for L in open("/var/lib/tor/cached-consensus"):
|
||||
if L.startswith("s "):
|
||||
flags = L.strip().split()
|
||||
if "Exit" in flags and "BadExit" not in flags and "Running" in flags and "Valid" in flags and "Stable" in flags:
|
||||
exits.append((router[1], router[6], flags))
|
||||
if L.startswith("r "):
|
||||
router = L.strip().split()
|
||||
allrouters.append(router[1])
|
||||
|
||||
duplicates = set(e[0] for e in exits if allrouters.count(e[0]) != 1)
|
||||
|
||||
print "All the good stable exits with unique names:"
|
||||
print
|
||||
|
||||
for exit in exits:
|
||||
name, ip, flags = exit
|
||||
if name not in duplicates:
|
||||
print name, ip, geoip.country_code_by_addr(ip)
|
||||
@@ -0,0 +1,577 @@
|
||||
"""
|
||||
Pure Python GeoIP API. The API is based off of U{MaxMind's C-based Python API<http://www.maxmind.com/app/python>},
|
||||
but the code itself is based on the U{pure PHP5 API<http://pear.php.net/package/Net_GeoIP/>}
|
||||
by Jim Winstead and Hans Lellelid.
|
||||
|
||||
It is mostly a drop-in replacement, except the
|
||||
C{new} and C{open} methods are gone. You should instantiate the L{GeoIP} class yourself:
|
||||
|
||||
C{gi = GeoIP('/path/to/GeoIP.dat', pygeoip.MEMORY_CACHE)}
|
||||
|
||||
@author: Jennifer Ennis <zaylea at gmail dot com>
|
||||
|
||||
@license:
|
||||
Copyright(C) 2004 MaxMind LLC
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/lgpl.txt>.
|
||||
"""
|
||||
|
||||
from __future__ import with_statement
|
||||
import os
|
||||
import math
|
||||
import socket
|
||||
import mmap
|
||||
|
||||
from const import *
|
||||
from util import ip2long
|
||||
|
||||
class GeoIPError(Exception):
|
||||
pass
|
||||
|
||||
class GeoIPMetaclass(type):
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
"""
|
||||
Singleton method to gets an instance without reparsing the db. Unique
|
||||
instances are instantiated based on the filename of the db. Flags are
|
||||
ignored for this, i.e. if you initialize one with STANDARD flag (default)
|
||||
and then try later to initialize with MEMORY_CACHE, it will still
|
||||
return the STANDARD one.
|
||||
"""
|
||||
|
||||
if not hasattr(cls, '_instances'):
|
||||
cls._instances = {}
|
||||
|
||||
if len(args) > 0:
|
||||
filename = args[0]
|
||||
elif 'filename' in kwargs:
|
||||
filename = kwargs['filename']
|
||||
|
||||
if not filename in cls._instances:
|
||||
cls._instances[filename] = type.__new__(cls, *args, **kwargs)
|
||||
|
||||
return cls._instances[filename]
|
||||
|
||||
GeoIPBase = GeoIPMetaclass('GeoIPBase', (object,), {})
|
||||
|
||||
class GeoIP(GeoIPBase):
|
||||
|
||||
def __init__(self, filename, flags=0):
|
||||
"""
|
||||
Initialize the class.
|
||||
|
||||
@param filename: path to a geoip database
|
||||
@type filename: str
|
||||
@param flags: flags that affect how the database is processed.
|
||||
Currently the only supported flags are STANDARD, MEMORY_CACHE, and
|
||||
MMAP_CACHE.
|
||||
@type flags: int
|
||||
"""
|
||||
self._filename = filename
|
||||
self._flags = flags
|
||||
|
||||
if self._flags & MMAP_CACHE:
|
||||
with open(filename, 'rb') as f:
|
||||
self._filehandle = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
|
||||
|
||||
else:
|
||||
self._filehandle = open(filename, 'rb')
|
||||
|
||||
if self._flags & MEMORY_CACHE:
|
||||
self._memoryBuffer = self._filehandle.read()
|
||||
|
||||
self._setup_segments()
|
||||
|
||||
def _setup_segments(self):
|
||||
"""
|
||||
Parses the database file to determine what kind of database is being used and setup
|
||||
segment sizes and start points that will be used by the seek*() methods later.
|
||||
"""
|
||||
self._databaseType = COUNTRY_EDITION
|
||||
self._recordLength = STANDARD_RECORD_LENGTH
|
||||
|
||||
filepos = self._filehandle.tell()
|
||||
self._filehandle.seek(-3, os.SEEK_END)
|
||||
|
||||
for i in range(STRUCTURE_INFO_MAX_SIZE):
|
||||
delim = self._filehandle.read(3)
|
||||
|
||||
if delim == (chr(255) * 3):
|
||||
self._databaseType = ord(self._filehandle.read(1))
|
||||
|
||||
if (self._databaseType >= 106):
|
||||
# backwards compatibility with databases from April 2003 and earlier
|
||||
self._databaseType -= 105
|
||||
|
||||
if self._databaseType == REGION_EDITION_REV0:
|
||||
self._databaseSegments = STATE_BEGIN_REV0
|
||||
|
||||
elif self._databaseType == REGION_EDITION_REV1:
|
||||
self._databaseSegments = STATE_BEGIN_REV1
|
||||
|
||||
elif self._databaseType in (CITY_EDITION_REV0,
|
||||
CITY_EDITION_REV1,
|
||||
ORG_EDITION,
|
||||
ISP_EDITION,
|
||||
ASNUM_EDITION):
|
||||
self._databaseSegments = 0
|
||||
buf = self._filehandle.read(SEGMENT_RECORD_LENGTH)
|
||||
|
||||
for j in range(SEGMENT_RECORD_LENGTH):
|
||||
self._databaseSegments += (ord(buf[j]) << (j * 8))
|
||||
|
||||
if self._databaseType in (ORG_EDITION, ISP_EDITION):
|
||||
self._recordLength = ORG_RECORD_LENGTH
|
||||
|
||||
break
|
||||
else:
|
||||
self._filehandle.seek(-4, os.SEEK_CUR)
|
||||
|
||||
if self._databaseType == COUNTRY_EDITION:
|
||||
self._databaseSegments = COUNTRY_BEGIN
|
||||
|
||||
self._filehandle.seek(filepos, os.SEEK_SET)
|
||||
|
||||
def _lookup_country_id(self, addr):
|
||||
"""
|
||||
Get the country index.
|
||||
|
||||
This method is called by the _lookupCountryCode and _lookupCountryName
|
||||
methods. It looks up the index ('id') for the country which is the key
|
||||
for the code and name.
|
||||
|
||||
@param addr: The IP address
|
||||
@type addr: str
|
||||
@return: network byte order 32-bit integer
|
||||
@rtype: int
|
||||
"""
|
||||
|
||||
ipnum = ip2long(addr)
|
||||
|
||||
if not ipnum:
|
||||
raise ValueError("Invalid IP address: %s" % addr)
|
||||
|
||||
if self._databaseType != COUNTRY_EDITION:
|
||||
raise GeoIPError('Invalid database type; country_* methods expect '\
|
||||
'Country database')
|
||||
|
||||
return self._seek_country(ipnum) - COUNTRY_BEGIN
|
||||
|
||||
def _seek_country(self, ipnum):
|
||||
"""
|
||||
Using the record length and appropriate start points, seek to the
|
||||
country that corresponds to the converted IP address integer.
|
||||
|
||||
@param ipnum: result of ip2long conversion
|
||||
@type ipnum: int
|
||||
@return: offset of start of record
|
||||
@rtype: int
|
||||
"""
|
||||
offset = 0
|
||||
|
||||
for depth in range(31, -1, -1):
|
||||
|
||||
if self._flags & MEMORY_CACHE:
|
||||
startIndex = 2 * self._recordLength * offset
|
||||
length = 2 * self._recordLength
|
||||
endIndex = startIndex + length
|
||||
buf = self._memoryBuffer[startIndex:endIndex]
|
||||
else:
|
||||
self._filehandle.seek(2 * self._recordLength * offset, os.SEEK_SET)
|
||||
buf = self._filehandle.read(2 * self._recordLength)
|
||||
|
||||
x = [0,0]
|
||||
|
||||
for i in range(2):
|
||||
for j in range(self._recordLength):
|
||||
x[i] += ord(buf[self._recordLength * i + j]) << (j * 8)
|
||||
|
||||
if ipnum & (1 << depth):
|
||||
|
||||
if x[1] >= self._databaseSegments:
|
||||
return x[1]
|
||||
|
||||
offset = x[1]
|
||||
|
||||
else:
|
||||
|
||||
if x[0] >= self._databaseSegments:
|
||||
return x[0]
|
||||
|
||||
offset = x[0]
|
||||
|
||||
|
||||
raise Exception('Error traversing database - perhaps it is corrupt?')
|
||||
|
||||
def _get_org(self, ipnum):
|
||||
"""
|
||||
Seek and return organization (or ISP) name for converted IP addr.
|
||||
@param ipnum: Converted IP address
|
||||
@type ipnum: int
|
||||
@return: org/isp name
|
||||
@rtype: str
|
||||
"""
|
||||
|
||||
seek_org = self._seek_country(ipnum)
|
||||
if seek_org == self._databaseSegments:
|
||||
return None
|
||||
|
||||
record_pointer = seek_org + (2 * self._recordLength - 1) * self._databaseSegments
|
||||
|
||||
self._filehandle.seek(record_pointer, os.SEEK_SET)
|
||||
|
||||
org_buf = self._filehandle.read(MAX_ORG_RECORD_LENGTH)
|
||||
|
||||
return org_buf[:org_buf.index(chr(0))]
|
||||
|
||||
def _get_region(self, ipnum):
|
||||
"""
|
||||
Seek and return the region info (dict containing country_code and region_name).
|
||||
|
||||
@param ipnum: converted IP address
|
||||
@type ipnum: int
|
||||
@return: dict containing country_code and region_name
|
||||
@rtype: dict
|
||||
"""
|
||||
country_code = ''
|
||||
region = ''
|
||||
|
||||
if self._databaseType == REGION_EDITION_REV0:
|
||||
seek_country = self._seek_country(ipnum)
|
||||
seek_region = seek_country - STATE_BEGIN_REV0
|
||||
if seek_region >= 1000:
|
||||
country_code = 'US'
|
||||
region = ''.join([chr((seek_region / 1000) / 26 + 65), chr((seek_region / 1000) % 26 + 65)])
|
||||
else:
|
||||
country_code = COUNTRY_CODES[seek_region]
|
||||
region = ''
|
||||
elif self._databaseType == REGION_EDITION_REV1:
|
||||
seek_country = self._seek_country(ipnum)
|
||||
seek_region = seek_country - STATE_BEGIN_REV1
|
||||
if seek_region < US_OFFSET:
|
||||
country_code = '';
|
||||
region = ''
|
||||
elif seek_region < CANADA_OFFSET:
|
||||
country_code = 'US'
|
||||
region = ''.join([chr((seek_region - US_OFFSET) / 26 + 65), chr((seek_region - US_OFFSET) % 26 + 65)])
|
||||
elif seek_region < WORLD_OFFSET:
|
||||
country_code = 'CA'
|
||||
region = ''.join([chr((seek_region - CANADA_OFFSET) / 26 + 65), chr((seek_region - CANADA_OFFSET) % 26 + 65)])
|
||||
else:
|
||||
i = (seek_region - WORLD_OFFSET) / FIPS_RANGE
|
||||
if i in COUNTRY_CODES:
|
||||
country_code = COUNTRY_CODES[(seek_region - WORLD_OFFSET) / FIPS_RANGE]
|
||||
else:
|
||||
country_code = ''
|
||||
region = ''
|
||||
|
||||
elif self._databaseType in (CITY_EDITION_REV0, CITY_EDITION_REV1):
|
||||
rec = self._get_record(ipnum)
|
||||
country_code = rec['country_code']
|
||||
region = rec['region_name']
|
||||
|
||||
return {'country_code' : country_code, 'region_name' : region }
|
||||
|
||||
def _get_record(self, ipnum):
|
||||
"""
|
||||
Populate location dict for converted IP.
|
||||
|
||||
@param ipnum: converted IP address
|
||||
@type ipnum: int
|
||||
@return: dict with country_code, country_code3, country_name,
|
||||
region, city, postal_code, latitude, longitude,
|
||||
dma_code, metro_code, area_code, region_name, time_zone
|
||||
@rtype: dict
|
||||
"""
|
||||
seek_country = self._seek_country(ipnum)
|
||||
if seek_country == self._databaseSegments:
|
||||
return None
|
||||
|
||||
record_pointer = seek_country + (2 * self._recordLength - 1) * self._databaseSegments
|
||||
|
||||
self._filehandle.seek(record_pointer, os.SEEK_SET)
|
||||
record_buf = self._filehandle.read(FULL_RECORD_LENGTH)
|
||||
|
||||
record = {}
|
||||
|
||||
record_buf_pos = 0
|
||||
char = ord(record_buf[record_buf_pos])
|
||||
record['country_code'] = COUNTRY_CODES[char]
|
||||
record['country_code3'] = COUNTRY_CODES3[char]
|
||||
record['country_name'] = COUNTRY_NAMES[char]
|
||||
record_buf_pos += 1
|
||||
str_length = 0
|
||||
|
||||
# get region
|
||||
char = ord(record_buf[record_buf_pos+str_length])
|
||||
while (char != 0):
|
||||
str_length += 1
|
||||
char = ord(record_buf[record_buf_pos+str_length])
|
||||
|
||||
if str_length > 0:
|
||||
record['region_name'] = record_buf[record_buf_pos:record_buf_pos+str_length]
|
||||
|
||||
record_buf_pos += str_length + 1
|
||||
str_length = 0
|
||||
|
||||
# get city
|
||||
char = ord(record_buf[record_buf_pos+str_length])
|
||||
while (char != 0):
|
||||
str_length += 1
|
||||
char = ord(record_buf[record_buf_pos+str_length])
|
||||
|
||||
if str_length > 0:
|
||||
record['city'] = record_buf[record_buf_pos:record_buf_pos+str_length]
|
||||
|
||||
record_buf_pos += str_length + 1
|
||||
str_length = 0
|
||||
|
||||
# get the postal code
|
||||
char = ord(record_buf[record_buf_pos+str_length])
|
||||
while (char != 0):
|
||||
str_length += 1
|
||||
char = ord(record_buf[record_buf_pos+str_length])
|
||||
|
||||
if str_length > 0:
|
||||
record['postal_code'] = record_buf[record_buf_pos:record_buf_pos+str_length]
|
||||
else:
|
||||
record['postal_code'] = None
|
||||
|
||||
record_buf_pos += str_length + 1
|
||||
str_length = 0
|
||||
|
||||
latitude = 0
|
||||
longitude = 0
|
||||
for j in range(3):
|
||||
char = ord(record_buf[record_buf_pos])
|
||||
record_buf_pos += 1
|
||||
latitude += (char << (j * 8))
|
||||
|
||||
record['latitude'] = (latitude/10000.0) - 180.0
|
||||
|
||||
for j in range(3):
|
||||
char = ord(record_buf[record_buf_pos])
|
||||
record_buf_pos += 1
|
||||
longitude += (char << (j * 8))
|
||||
|
||||
record['longitude'] = (longitude/10000.0) - 180.0
|
||||
|
||||
if self._databaseType == CITY_EDITION_REV1:
|
||||
dmaarea_combo = 0
|
||||
if record['country_code'] == 'US':
|
||||
for j in range(3):
|
||||
char = ord(record_buf[record_buf_pos])
|
||||
record_buf_pos += 1
|
||||
dmaarea_combo += (char << (j*8))
|
||||
|
||||
record['dma_code'] = int(math.floor(dmaarea_combo/1000))
|
||||
record['area_code'] = dmaarea_combo%1000
|
||||
else:
|
||||
record['dma_code'] = 0
|
||||
record['area_code'] = 0
|
||||
|
||||
return record
|
||||
|
||||
def country_code_by_addr(self, addr):
|
||||
"""
|
||||
Returns 2-letter country code (e.g. 'US') for specified IP address.
|
||||
Use this method if you have a Country, Region, or City database.
|
||||
|
||||
@param addr: IP address
|
||||
@type addr: str
|
||||
@return: 2-letter country code
|
||||
@rtype: str
|
||||
"""
|
||||
try:
|
||||
if self._databaseType == COUNTRY_EDITION:
|
||||
country_id = self._lookup_country_id(addr)
|
||||
return COUNTRY_CODES[country_id]
|
||||
elif self._databaseType in (REGION_EDITION_REV0, REGION_EDITION_REV1,
|
||||
CITY_EDITION_REV0, CITY_EDITION_REV1):
|
||||
return self.region_by_addr(addr)['country_code']
|
||||
else:
|
||||
raise GeoIPError('Invalid database type; country_* methods expect '\
|
||||
'Country, City, or Region database')
|
||||
|
||||
except ValueError:
|
||||
raise GeoIPError('*_by_addr methods only accept IP addresses. Use *_by_name for hostnames. (Address: %s)' % addr)
|
||||
|
||||
def country_code_by_name(self, hostname):
|
||||
"""
|
||||
Returns 2-letter country code (e.g. 'US') for specified hostname.
|
||||
Use this method if you have a Country, Region, or City database.
|
||||
|
||||
@param hostname: host name
|
||||
@type hostname: str
|
||||
@return: 2-letter country code
|
||||
@rtype: str
|
||||
"""
|
||||
addr = socket.gethostbyname(hostname)
|
||||
|
||||
return self.country_code_by_addr(addr)
|
||||
|
||||
def country_name_by_addr(self, addr):
|
||||
"""
|
||||
Returns full country name for specified IP address.
|
||||
Use this method if you have a Country or City database.
|
||||
|
||||
@param addr: IP address
|
||||
@type addr: str
|
||||
@return: country name
|
||||
@rtype: str
|
||||
"""
|
||||
try:
|
||||
if self._databaseType == COUNTRY_EDITION:
|
||||
country_id = self._lookup_country_id(addr)
|
||||
return COUNTRY_NAMES[country_id]
|
||||
elif self._databaseType in (CITY_EDITION_REV0, CITY_EDITION_REV1):
|
||||
return self.record_by_addr(addr)['country_name']
|
||||
else:
|
||||
raise GeoIPError('Invalid database type; country_* methods expect '\
|
||||
'Country or City database')
|
||||
except ValueError:
|
||||
raise GeoIPError('*_by_addr methods only accept IP addresses. Use *_by_name for hostnames. (Address: %s)' % addr)
|
||||
|
||||
def country_name_by_name(self, hostname):
|
||||
"""
|
||||
Returns full country name for specified hostname.
|
||||
Use this method if you have a Country database.
|
||||
|
||||
@param hostname: host name
|
||||
@type hostname: str
|
||||
@return: country name
|
||||
@rtype: str
|
||||
"""
|
||||
addr = socket.gethostbyname(hostname)
|
||||
return self.country_name_by_addr(addr)
|
||||
|
||||
def org_by_addr(self, addr):
|
||||
"""
|
||||
Lookup the organization (or ISP) for given IP address.
|
||||
Use this method if you have an Organization/ISP database.
|
||||
|
||||
@param addr: IP address
|
||||
@type addr: str
|
||||
@return: organization or ISP name
|
||||
@rtype: str
|
||||
"""
|
||||
try:
|
||||
ipnum = ip2long(addr)
|
||||
|
||||
if not ipnum:
|
||||
raise ValueError("Invalid IP address: %s" % addr)
|
||||
|
||||
if self._databaseType not in (ORG_EDITION, ISP_EDITION):
|
||||
raise GeoIPError('Invalid database type; org_* methods expect '\
|
||||
'Org/ISP database')
|
||||
|
||||
return self._get_org(ipnum)
|
||||
except ValueError:
|
||||
raise GeoIPError('*_by_addr methods only accept IP addresses. Use *_by_name for hostnames. (Address: %s)' % addr)
|
||||
|
||||
def org_by_name(self, hostname):
|
||||
"""
|
||||
Lookup the organization (or ISP) for hostname.
|
||||
Use this method if you have an Organization/ISP database.
|
||||
|
||||
@param hostname: host name
|
||||
@type hostname: str
|
||||
@return: organization or ISP name
|
||||
@rtype: str
|
||||
"""
|
||||
addr = socket.gethostbyname(hostname)
|
||||
|
||||
return self.org_by_addr(addr)
|
||||
|
||||
def record_by_addr(self, addr):
|
||||
"""
|
||||
Look up the record for a given IP address.
|
||||
Use this method if you have a City database.
|
||||
|
||||
@param addr: IP address
|
||||
@type addr: str
|
||||
@return: dict with country_code, country_code3, country_name,
|
||||
region, city, postal_code, latitude, longitude,
|
||||
dma_code, metro_code, area_code, region_name, time_zone
|
||||
@rtype: dict
|
||||
"""
|
||||
try:
|
||||
ipnum = ip2long(addr)
|
||||
|
||||
if not ipnum:
|
||||
raise ValueError("Invalid IP address: %s" % addr)
|
||||
|
||||
if not self._databaseType in (CITY_EDITION_REV0, CITY_EDITION_REV1):
|
||||
raise GeoIPError('Invalid database type; record_* methods expect City database')
|
||||
|
||||
return self._get_record(ipnum)
|
||||
except ValueError:
|
||||
raise GeoIPError('*_by_addr methods only accept IP addresses. Use *_by_name for hostnames. (Address: %s)' % addr)
|
||||
|
||||
def record_by_name(self, hostname):
|
||||
"""
|
||||
Look up the record for a given hostname.
|
||||
Use this method if you have a City database.
|
||||
|
||||
@param hostname: host name
|
||||
@type hostname: str
|
||||
@return: dict with country_code, country_code3, country_name,
|
||||
region, city, postal_code, latitude, longitude,
|
||||
dma_code, metro_code, area_code, region_name, time_zone
|
||||
@rtype: dict
|
||||
"""
|
||||
addr = socket.gethostbyname(hostname)
|
||||
|
||||
return self.record_by_addr(addr)
|
||||
|
||||
def region_by_addr(self, addr):
|
||||
"""
|
||||
Lookup the region for given IP address.
|
||||
Use this method if you have a Region database.
|
||||
|
||||
@param addr: IP address
|
||||
@type addr: str
|
||||
@return: dict containing country_code, region,
|
||||
and region_name
|
||||
@rtype: dict
|
||||
"""
|
||||
try:
|
||||
ipnum = ip2long(addr)
|
||||
|
||||
if not ipnum:
|
||||
raise ValueError("Invalid IP address: %s" % addr)
|
||||
|
||||
if not self._databaseType in (REGION_EDITION_REV0, REGION_EDITION_REV1,
|
||||
CITY_EDITION_REV0, CITY_EDITION_REV1):
|
||||
raise GeoIPError('Invalid database type; region_* methods expect '\
|
||||
'Region or City database')
|
||||
|
||||
return self._get_region(ipnum)
|
||||
except ValueError:
|
||||
raise GeoIPError('*_by_addr methods only accept IP addresses. Use *_by_name for hostnames. (Address: %s)' % addr)
|
||||
|
||||
def region_by_name(self, hostname):
|
||||
"""
|
||||
Lookup the region for given hostname.
|
||||
Use this method if you have a Region database.
|
||||
|
||||
@param hostname: host name
|
||||
@type hostname: str
|
||||
@return: dict containing country_code, region,
|
||||
and region_name
|
||||
@rtype: dict
|
||||
"""
|
||||
addr = socket.gethostbyname(hostname)
|
||||
return self.region_by_addr(addr)
|
||||
|
||||
@@ -0,0 +1,382 @@
|
||||
"""
|
||||
Constants needed for parsing binary GeoIP databases. It is part of the pygeoip
|
||||
package.
|
||||
|
||||
@author: Jennifer Ennis <zaylea at gmail dot com>
|
||||
|
||||
@license:
|
||||
Copyright(C) 2004 MaxMind LLC
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/lgpl.txt>.
|
||||
"""
|
||||
|
||||
GEOIP_STANDARD = 0
|
||||
GEOIP_MEMORY_CACHE = 1
|
||||
|
||||
DMA_MAP = {
|
||||
500 : 'Portland-Auburn, ME',
|
||||
501 : 'New York, NY',
|
||||
502 : 'Binghamton, NY',
|
||||
503 : 'Macon, GA',
|
||||
504 : 'Philadelphia, PA',
|
||||
505 : 'Detroit, MI',
|
||||
506 : 'Boston, MA',
|
||||
507 : 'Savannah, GA',
|
||||
508 : 'Pittsburgh, PA',
|
||||
509 : 'Ft Wayne, IN',
|
||||
510 : 'Cleveland, OH',
|
||||
511 : 'Washington, DC',
|
||||
512 : 'Baltimore, MD',
|
||||
513 : 'Flint, MI',
|
||||
514 : 'Buffalo, NY',
|
||||
515 : 'Cincinnati, OH',
|
||||
516 : 'Erie, PA',
|
||||
517 : 'Charlotte, NC',
|
||||
518 : 'Greensboro, NC',
|
||||
519 : 'Charleston, SC',
|
||||
520 : 'Augusta, GA',
|
||||
521 : 'Providence, RI',
|
||||
522 : 'Columbus, GA',
|
||||
523 : 'Burlington, VT',
|
||||
524 : 'Atlanta, GA',
|
||||
525 : 'Albany, GA',
|
||||
526 : 'Utica-Rome, NY',
|
||||
527 : 'Indianapolis, IN',
|
||||
528 : 'Miami, FL',
|
||||
529 : 'Louisville, KY',
|
||||
530 : 'Tallahassee, FL',
|
||||
531 : 'Tri-Cities, TN',
|
||||
532 : 'Albany-Schenectady-Troy, NY',
|
||||
533 : 'Hartford, CT',
|
||||
534 : 'Orlando, FL',
|
||||
535 : 'Columbus, OH',
|
||||
536 : 'Youngstown-Warren, OH',
|
||||
537 : 'Bangor, ME',
|
||||
538 : 'Rochester, NY',
|
||||
539 : 'Tampa, FL',
|
||||
540 : 'Traverse City-Cadillac, MI',
|
||||
541 : 'Lexington, KY',
|
||||
542 : 'Dayton, OH',
|
||||
543 : 'Springfield-Holyoke, MA',
|
||||
544 : 'Norfolk-Portsmouth, VA',
|
||||
545 : 'Greenville-New Bern-Washington, NC',
|
||||
546 : 'Columbia, SC',
|
||||
547 : 'Toledo, OH',
|
||||
548 : 'West Palm Beach, FL',
|
||||
549 : 'Watertown, NY',
|
||||
550 : 'Wilmington, NC',
|
||||
551 : 'Lansing, MI',
|
||||
552 : 'Presque Isle, ME',
|
||||
553 : 'Marquette, MI',
|
||||
554 : 'Wheeling, WV',
|
||||
555 : 'Syracuse, NY',
|
||||
556 : 'Richmond-Petersburg, VA',
|
||||
557 : 'Knoxville, TN',
|
||||
558 : 'Lima, OH',
|
||||
559 : 'Bluefield-Beckley-Oak Hill, WV',
|
||||
560 : 'Raleigh-Durham, NC',
|
||||
561 : 'Jacksonville, FL',
|
||||
563 : 'Grand Rapids, MI',
|
||||
564 : 'Charleston-Huntington, WV',
|
||||
565 : 'Elmira, NY',
|
||||
566 : 'Harrisburg-Lancaster-Lebanon-York, PA',
|
||||
567 : 'Greenville-Spartenburg, SC',
|
||||
569 : 'Harrisonburg, VA',
|
||||
570 : 'Florence-Myrtle Beach, SC',
|
||||
571 : 'Ft Myers, FL',
|
||||
573 : 'Roanoke-Lynchburg, VA',
|
||||
574 : 'Johnstown-Altoona, PA',
|
||||
575 : 'Chattanooga, TN',
|
||||
576 : 'Salisbury, MD',
|
||||
577 : 'Wilkes Barre-Scranton, PA',
|
||||
581 : 'Terre Haute, IN',
|
||||
582 : 'Lafayette, IN',
|
||||
583 : 'Alpena, MI',
|
||||
584 : 'Charlottesville, VA',
|
||||
588 : 'South Bend, IN',
|
||||
592 : 'Gainesville, FL',
|
||||
596 : 'Zanesville, OH',
|
||||
597 : 'Parkersburg, WV',
|
||||
598 : 'Clarksburg-Weston, WV',
|
||||
600 : 'Corpus Christi, TX',
|
||||
602 : 'Chicago, IL',
|
||||
603 : 'Joplin-Pittsburg, MO',
|
||||
604 : 'Columbia-Jefferson City, MO',
|
||||
605 : 'Topeka, KS',
|
||||
606 : 'Dothan, AL',
|
||||
609 : 'St Louis, MO',
|
||||
610 : 'Rockford, IL',
|
||||
611 : 'Rochester-Mason City-Austin, MN',
|
||||
612 : 'Shreveport, LA',
|
||||
613 : 'Minneapolis-St Paul, MN',
|
||||
616 : 'Kansas City, MO',
|
||||
617 : 'Milwaukee, WI',
|
||||
618 : 'Houston, TX',
|
||||
619 : 'Springfield, MO',
|
||||
620 : 'Tuscaloosa, AL',
|
||||
622 : 'New Orleans, LA',
|
||||
623 : 'Dallas-Fort Worth, TX',
|
||||
624 : 'Sioux City, IA',
|
||||
625 : 'Waco-Temple-Bryan, TX',
|
||||
626 : 'Victoria, TX',
|
||||
627 : 'Wichita Falls, TX',
|
||||
628 : 'Monroe, LA',
|
||||
630 : 'Birmingham, AL',
|
||||
631 : 'Ottumwa-Kirksville, IA',
|
||||
632 : 'Paducah, KY',
|
||||
633 : 'Odessa-Midland, TX',
|
||||
634 : 'Amarillo, TX',
|
||||
635 : 'Austin, TX',
|
||||
636 : 'Harlingen, TX',
|
||||
637 : 'Cedar Rapids-Waterloo, IA',
|
||||
638 : 'St Joseph, MO',
|
||||
639 : 'Jackson, TN',
|
||||
640 : 'Memphis, TN',
|
||||
641 : 'San Antonio, TX',
|
||||
642 : 'Lafayette, LA',
|
||||
643 : 'Lake Charles, LA',
|
||||
644 : 'Alexandria, LA',
|
||||
646 : 'Anniston, AL',
|
||||
647 : 'Greenwood-Greenville, MS',
|
||||
648 : 'Champaign-Springfield-Decatur, IL',
|
||||
649 : 'Evansville, IN',
|
||||
650 : 'Oklahoma City, OK',
|
||||
651 : 'Lubbock, TX',
|
||||
652 : 'Omaha, NE',
|
||||
656 : 'Panama City, FL',
|
||||
657 : 'Sherman, TX',
|
||||
658 : 'Green Bay-Appleton, WI',
|
||||
659 : 'Nashville, TN',
|
||||
661 : 'San Angelo, TX',
|
||||
662 : 'Abilene-Sweetwater, TX',
|
||||
669 : 'Madison, WI',
|
||||
670 : 'Ft Smith-Fay-Springfield, AR',
|
||||
671 : 'Tulsa, OK',
|
||||
673 : 'Columbus-Tupelo-West Point, MS',
|
||||
675 : 'Peoria-Bloomington, IL',
|
||||
676 : 'Duluth, MN',
|
||||
678 : 'Wichita, KS',
|
||||
679 : 'Des Moines, IA',
|
||||
682 : 'Davenport-Rock Island-Moline, IL',
|
||||
686 : 'Mobile, AL',
|
||||
687 : 'Minot-Bismarck-Dickinson, ND',
|
||||
691 : 'Huntsville, AL',
|
||||
692 : 'Beaumont-Port Author, TX',
|
||||
693 : 'Little Rock-Pine Bluff, AR',
|
||||
698 : 'Montgomery, AL',
|
||||
702 : 'La Crosse-Eau Claire, WI',
|
||||
705 : 'Wausau-Rhinelander, WI',
|
||||
709 : 'Tyler-Longview, TX',
|
||||
710 : 'Hattiesburg-Laurel, MS',
|
||||
711 : 'Meridian, MS',
|
||||
716 : 'Baton Rouge, LA',
|
||||
717 : 'Quincy, IL',
|
||||
718 : 'Jackson, MS',
|
||||
722 : 'Lincoln-Hastings, NE',
|
||||
724 : 'Fargo-Valley City, ND',
|
||||
725 : 'Sioux Falls, SD',
|
||||
734 : 'Jonesboro, AR',
|
||||
736 : 'Bowling Green, KY',
|
||||
737 : 'Mankato, MN',
|
||||
740 : 'North Platte, NE',
|
||||
743 : 'Anchorage, AK',
|
||||
744 : 'Honolulu, HI',
|
||||
745 : 'Fairbanks, AK',
|
||||
746 : 'Biloxi-Gulfport, MS',
|
||||
747 : 'Juneau, AK',
|
||||
749 : 'Laredo, TX',
|
||||
751 : 'Denver, CO',
|
||||
752 : 'Colorado Springs, CO',
|
||||
753 : 'Phoenix, AZ',
|
||||
754 : 'Butte-Bozeman, MT',
|
||||
755 : 'Great Falls, MT',
|
||||
756 : 'Billings, MT',
|
||||
757 : 'Boise, ID',
|
||||
758 : 'Idaho Falls-Pocatello, ID',
|
||||
759 : 'Cheyenne, WY',
|
||||
760 : 'Twin Falls, ID',
|
||||
762 : 'Missoula, MT',
|
||||
764 : 'Rapid City, SD',
|
||||
765 : 'El Paso, TX',
|
||||
766 : 'Helena, MT',
|
||||
767 : 'Casper-Riverton, WY',
|
||||
770 : 'Salt Lake City, UT',
|
||||
771 : 'Yuma, AZ',
|
||||
773 : 'Grand Junction, CO',
|
||||
789 : 'Tucson, AZ',
|
||||
790 : 'Albuquerque, NM',
|
||||
798 : 'Glendive, MT',
|
||||
800 : 'Bakersfield, CA',
|
||||
801 : 'Eugene, OR',
|
||||
802 : 'Eureka, CA',
|
||||
803 : 'Los Angeles, CA',
|
||||
804 : 'Palm Springs, CA',
|
||||
807 : 'San Francisco, CA',
|
||||
810 : 'Yakima-Pasco, WA',
|
||||
811 : 'Reno, NV',
|
||||
813 : 'Medford-Klamath Falls, OR',
|
||||
819 : 'Seattle-Tacoma, WA',
|
||||
820 : 'Portland, OR',
|
||||
821 : 'Bend, OR',
|
||||
825 : 'San Diego, CA',
|
||||
828 : 'Monterey-Salinas, CA',
|
||||
839 : 'Las Vegas, NV',
|
||||
855 : 'Santa Barbara, CA',
|
||||
862 : 'Sacramento, CA',
|
||||
866 : 'Fresno, CA',
|
||||
868 : 'Chico-Redding, CA',
|
||||
881 : 'Spokane, WA'
|
||||
}
|
||||
|
||||
COUNTRY_CODES = (
|
||||
'', 'AP', 'EU', 'AD', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', 'AN', 'AO', 'AQ',
|
||||
'AR', 'AS', 'AT', 'AU', 'AW', 'AZ', 'BA', 'BB', 'BD', 'BE', 'BF', 'BG', 'BH',
|
||||
'BI', 'BJ', 'BM', 'BN', 'BO', 'BR', 'BS', 'BT', 'BV', 'BW', 'BY', 'BZ', 'CA',
|
||||
'CC', 'CD', 'CF', 'CG', 'CH', 'CI', 'CK', 'CL', 'CM', 'CN', 'CO', 'CR', 'CU',
|
||||
'CV', 'CX', 'CY', 'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO', 'DZ', 'EC', 'EE', 'EG',
|
||||
'EH', 'ER', 'ES', 'ET', 'FI', 'FJ', 'FK', 'FM', 'FO', 'FR', 'FX', 'GA', 'GB',
|
||||
'GD', 'GE', 'GF', 'GH', 'GI', 'GL', 'GM', 'GN', 'GP', 'GQ', 'GR', 'GS', 'GT',
|
||||
'GU', 'GW', 'GY', 'HK', 'HM', 'HN', 'HR', 'HT', 'HU', 'ID', 'IE', 'IL', 'IN',
|
||||
'IO', 'IQ', 'IR', 'IS', 'IT', 'JM', 'JO', 'JP', 'KE', 'KG', 'KH', 'KI', 'KM',
|
||||
'KN', 'KP', 'KR', 'KW', 'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK', 'LR', 'LS',
|
||||
'LT', 'LU', 'LV', 'LY', 'MA', 'MC', 'MD', 'MG', 'MH', 'MK', 'ML', 'MM', 'MN',
|
||||
'MO', 'MP', 'MQ', 'MR', 'MS', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA',
|
||||
'NC', 'NE', 'NF', 'NG', 'NI', 'NL', 'NO', 'NP', 'NR', 'NU', 'NZ', 'OM', 'PA',
|
||||
'PE', 'PF', 'PG', 'PH', 'PK', 'PL', 'PM', 'PN', 'PR', 'PS', 'PT', 'PW', 'PY',
|
||||
'QA', 'RE', 'RO', 'RU', 'RW', 'SA', 'SB', 'SC', 'SD', 'SE', 'SG', 'SH', 'SI',
|
||||
'SJ', 'SK', 'SL', 'SM', 'SN', 'SO', 'SR', 'ST', 'SV', 'SY', 'SZ', 'TC', 'TD',
|
||||
'TF', 'TG', 'TH', 'TJ', 'TK', 'TM', 'TN', 'TO', 'TL', 'TR', 'TT', 'TV', 'TW',
|
||||
'TZ', 'UA', 'UG', 'UM', 'US', 'UY', 'UZ', 'VA', 'VC', 'VE', 'VG', 'VI', 'VN',
|
||||
'VU', 'WF', 'WS', 'YE', 'YT', 'RS', 'ZA', 'ZM', 'ME', 'ZW', 'A1', 'A2', 'O1',
|
||||
'AX', 'GG', 'IM', 'JE', 'BL', 'MF'
|
||||
)
|
||||
|
||||
COUNTRY_CODES3 = (
|
||||
'','AP','EU','AND','ARE','AFG','ATG','AIA','ALB','ARM','ANT','AGO','AQ','ARG',
|
||||
'ASM','AUT','AUS','ABW','AZE','BIH','BRB','BGD','BEL','BFA','BGR','BHR','BDI',
|
||||
'BEN','BMU','BRN','BOL','BRA','BHS','BTN','BV','BWA','BLR','BLZ','CAN','CC',
|
||||
'COD','CAF','COG','CHE','CIV','COK','CHL','CMR','CHN','COL','CRI','CUB','CPV',
|
||||
'CX','CYP','CZE','DEU','DJI','DNK','DMA','DOM','DZA','ECU','EST','EGY','ESH',
|
||||
'ERI','ESP','ETH','FIN','FJI','FLK','FSM','FRO','FRA','FX','GAB','GBR','GRD',
|
||||
'GEO','GUF','GHA','GIB','GRL','GMB','GIN','GLP','GNQ','GRC','GS','GTM','GUM',
|
||||
'GNB','GUY','HKG','HM','HND','HRV','HTI','HUN','IDN','IRL','ISR','IND','IO',
|
||||
'IRQ','IRN','ISL','ITA','JAM','JOR','JPN','KEN','KGZ','KHM','KIR','COM','KNA',
|
||||
'PRK','KOR','KWT','CYM','KAZ','LAO','LBN','LCA','LIE','LKA','LBR','LSO','LTU',
|
||||
'LUX','LVA','LBY','MAR','MCO','MDA','MDG','MHL','MKD','MLI','MMR','MNG','MAC',
|
||||
'MNP','MTQ','MRT','MSR','MLT','MUS','MDV','MWI','MEX','MYS','MOZ','NAM','NCL',
|
||||
'NER','NFK','NGA','NIC','NLD','NOR','NPL','NRU','NIU','NZL','OMN','PAN','PER',
|
||||
'PYF','PNG','PHL','PAK','POL','SPM','PCN','PRI','PSE','PRT','PLW','PRY','QAT',
|
||||
'REU','ROU','RUS','RWA','SAU','SLB','SYC','SDN','SWE','SGP','SHN','SVN','SJM',
|
||||
'SVK','SLE','SMR','SEN','SOM','SUR','STP','SLV','SYR','SWZ','TCA','TCD','TF',
|
||||
'TGO','THA','TJK','TKL','TLS','TKM','TUN','TON','TUR','TTO','TUV','TWN','TZA',
|
||||
'UKR','UGA','UM','USA','URY','UZB','VAT','VCT','VEN','VGB','VIR','VNM','VUT',
|
||||
'WLF','WSM','YEM','YT','SRB','ZAF','ZMB','MNE','ZWE','A1','A2','O1',
|
||||
'ALA','GGY','IMN','JEY','BLM','MAF'
|
||||
)
|
||||
|
||||
COUNTRY_NAMES = (
|
||||
"", "Asia/Pacific Region", "Europe", "Andorra", "United Arab Emirates",
|
||||
"Afghanistan", "Antigua and Barbuda", "Anguilla", "Albania", "Armenia",
|
||||
"Netherlands Antilles", "Angola", "Antarctica", "Argentina", "American Samoa",
|
||||
"Austria", "Australia", "Aruba", "Azerbaijan", "Bosnia and Herzegovina",
|
||||
"Barbados", "Bangladesh", "Belgium", "Burkina Faso", "Bulgaria", "Bahrain",
|
||||
"Burundi", "Benin", "Bermuda", "Brunei Darussalam", "Bolivia", "Brazil",
|
||||
"Bahamas", "Bhutan", "Bouvet Island", "Botswana", "Belarus", "Belize",
|
||||
"Canada", "Cocos (Keeling) Islands", "Congo, The Democratic Republic of the",
|
||||
"Central African Republic", "Congo", "Switzerland", "Cote D'Ivoire", "Cook Islands",
|
||||
"Chile", "Cameroon", "China", "Colombia", "Costa Rica", "Cuba", "Cape Verde",
|
||||
"Christmas Island", "Cyprus", "Czech Republic", "Germany", "Djibouti",
|
||||
"Denmark", "Dominica", "Dominican Republic", "Algeria", "Ecuador", "Estonia",
|
||||
"Egypt", "Western Sahara", "Eritrea", "Spain", "Ethiopia", "Finland", "Fiji",
|
||||
"Falkland Islands (Malvinas)", "Micronesia, Federated States of", "Faroe Islands",
|
||||
"France", "France, Metropolitan", "Gabon", "United Kingdom",
|
||||
"Grenada", "Georgia", "French Guiana", "Ghana", "Gibraltar", "Greenland",
|
||||
"Gambia", "Guinea", "Guadeloupe", "Equatorial Guinea", "Greece",
|
||||
"South Georgia and the South Sandwich Islands",
|
||||
"Guatemala", "Guam", "Guinea-Bissau",
|
||||
"Guyana", "Hong Kong", "Heard Island and McDonald Islands", "Honduras",
|
||||
"Croatia", "Haiti", "Hungary", "Indonesia", "Ireland", "Israel", "India",
|
||||
"British Indian Ocean Territory", "Iraq", "Iran, Islamic Republic of",
|
||||
"Iceland", "Italy", "Jamaica", "Jordan", "Japan", "Kenya", "Kyrgyzstan",
|
||||
"Cambodia", "Kiribati", "Comoros", "Saint Kitts and Nevis",
|
||||
"Korea, Democratic People's Republic of",
|
||||
"Korea, Republic of", "Kuwait", "Cayman Islands",
|
||||
"Kazakstan", "Lao People's Democratic Republic", "Lebanon", "Saint Lucia",
|
||||
"Liechtenstein", "Sri Lanka", "Liberia", "Lesotho", "Lithuania", "Luxembourg",
|
||||
"Latvia", "Libyan Arab Jamahiriya", "Morocco", "Monaco", "Moldova, Republic of",
|
||||
"Madagascar", "Marshall Islands", "Macedonia",
|
||||
"Mali", "Myanmar", "Mongolia", "Macau", "Northern Mariana Islands",
|
||||
"Martinique", "Mauritania", "Montserrat", "Malta", "Mauritius", "Maldives",
|
||||
"Malawi", "Mexico", "Malaysia", "Mozambique", "Namibia", "New Caledonia",
|
||||
"Niger", "Norfolk Island", "Nigeria", "Nicaragua", "Netherlands", "Norway",
|
||||
"Nepal", "Nauru", "Niue", "New Zealand", "Oman", "Panama", "Peru", "French Polynesia",
|
||||
"Papua New Guinea", "Philippines", "Pakistan", "Poland", "Saint Pierre and Miquelon",
|
||||
"Pitcairn Islands", "Puerto Rico", "Palestinian Territory",
|
||||
"Portugal", "Palau", "Paraguay", "Qatar", "Reunion", "Romania",
|
||||
"Russian Federation", "Rwanda", "Saudi Arabia", "Solomon Islands",
|
||||
"Seychelles", "Sudan", "Sweden", "Singapore", "Saint Helena", "Slovenia",
|
||||
"Svalbard and Jan Mayen", "Slovakia", "Sierra Leone", "San Marino", "Senegal",
|
||||
"Somalia", "Suriname", "Sao Tome and Principe", "El Salvador", "Syrian Arab Republic",
|
||||
"Swaziland", "Turks and Caicos Islands", "Chad", "French Southern Territories",
|
||||
"Togo", "Thailand", "Tajikistan", "Tokelau", "Turkmenistan",
|
||||
"Tunisia", "Tonga", "Timor-Leste", "Turkey", "Trinidad and Tobago", "Tuvalu",
|
||||
"Taiwan", "Tanzania, United Republic of", "Ukraine",
|
||||
"Uganda", "United States Minor Outlying Islands", "United States", "Uruguay",
|
||||
"Uzbekistan", "Holy See (Vatican City State)", "Saint Vincent and the Grenadines",
|
||||
"Venezuela", "Virgin Islands, British", "Virgin Islands, U.S.",
|
||||
"Vietnam", "Vanuatu", "Wallis and Futuna", "Samoa", "Yemen", "Mayotte",
|
||||
"Serbia", "South Africa", "Zambia", "Montenegro", "Zimbabwe",
|
||||
"Anonymous Proxy","Satellite Provider","Other",
|
||||
"Aland Islands","Guernsey","Isle of Man","Jersey","Saint Barthelemy","Saint Martin"
|
||||
)
|
||||
|
||||
# storage / caching flags
|
||||
STANDARD = 0
|
||||
MEMORY_CACHE = 1
|
||||
MMAP_CACHE = 8
|
||||
|
||||
# Database structure constants
|
||||
COUNTRY_BEGIN = 16776960
|
||||
STATE_BEGIN_REV0 = 16700000
|
||||
STATE_BEGIN_REV1 = 16000000
|
||||
|
||||
STRUCTURE_INFO_MAX_SIZE = 20
|
||||
DATABASE_INFO_MAX_SIZE = 100
|
||||
|
||||
# Database editions
|
||||
COUNTRY_EDITION = 1
|
||||
REGION_EDITION_REV0 = 7
|
||||
REGION_EDITION_REV1 = 3
|
||||
CITY_EDITION_REV0 = 6
|
||||
CITY_EDITION_REV1 = 2
|
||||
ORG_EDITION = 5
|
||||
ISP_EDITION = 4
|
||||
PROXY_EDITION = 8
|
||||
ASNUM_EDITION = 9
|
||||
NETSPEED_EDITION = 11
|
||||
COUNTRY_EDITION_V6 = 12
|
||||
|
||||
SEGMENT_RECORD_LENGTH = 3
|
||||
STANDARD_RECORD_LENGTH = 3
|
||||
ORG_RECORD_LENGTH = 4
|
||||
MAX_RECORD_LENGTH = 4
|
||||
MAX_ORG_RECORD_LENGTH = 300
|
||||
FULL_RECORD_LENGTH = 50
|
||||
|
||||
US_OFFSET = 1
|
||||
CANADA_OFFSET = 677
|
||||
WORLD_OFFSET = 1353
|
||||
FIPS_RANGE = 360
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
"""
|
||||
Misc. utility functions. It is part of the pygeoip package.
|
||||
|
||||
@author: Jennifer Ennis <zaylea at gmail dot com>
|
||||
|
||||
@license:
|
||||
Copyright(C) 2004 MaxMind LLC
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/lgpl.txt>.
|
||||
"""
|
||||
|
||||
def ip2long(ip):
|
||||
"""
|
||||
Convert a IPv4 address into a 32-bit integer.
|
||||
|
||||
@param ip: quad-dotted IPv4 address
|
||||
@type ip: str
|
||||
@return: network byte order 32-bit integer
|
||||
@rtype: int
|
||||
"""
|
||||
ip_array = ip.split('.')
|
||||
ip_long = long(ip_array[0]) * 16777216 + long(ip_array[1]) * 65536 + long(ip_array[2]) * 256 + long(ip_array[3])
|
||||
return ip_long
|
||||
|
||||
Reference in New Issue
Block a user