Update my info :-)
[blockfinder.git] / blockfinder
bloba67fdd6a81436b5c9eb453159dbfe4a05027af4f
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
4 # For the people of Smubworld!
5 import urllib2
6 import os
7 import time
8 from optparse import OptionParser
9 import sys
10 from math import ceil, log
11 import sqlite3
12 import hashlib
13 import gzip
14 import socket
15 __program__ = 'blockfinder'
16 __url__ = 'http://github.com/ioerror/blockfinder/'
17 ___author__ = 'Jacob Appelbaum <jacob@appelbaum.net>, David <db@d1b.org>'
18 __copyright__ = 'Copyright (c) 2010'
19 __license__ = 'See LICENSE for licensing information'
20 __version__ = '3.1415'
22 try:
23 import GeoIP
24 except ImportError:
25 GeoIP = None
27 try:
28 from future import antigravity
29 except ImportError:
30 antigravity = None
32 try:
33 import IPy
34 except ImportError:
35 IPy = None
36 try:
37 import ipaddr as Ipaddr
38 except ImportError:
39 Ipaddr = None
42 class BlockFinderError(Exception):
43 pass
45 def update_progress_bar(percent_done, caption=""):
46 """Write a progress bar to the console"""
47 rows, columns = map(int, os.popen('stty size', 'r').read().split())
48 width = columns - 4 - len(caption)
49 sys.stdout.write("[%s>%s] %s\x1b[G" % (
50 "=" * int(percent_done*width),
51 "." * (width - int(percent_done * width)),
52 caption) )
53 sys.stdout.flush()
55 # XXX TODO:allow the use of a proxy
56 # Set up a proper Request object, set the user agent and if desired, a proxy
57 def fetch(url, useragent):
58 """ Fetch (with progress meter) and return the contents of a url. """
59 req = urllib2.Request(url)
60 req.add_header('User-agent', useragent)
61 #req.set_proxy(host, type)
62 fetcher = urllib2.urlopen(req)
63 length_header = fetcher.headers.get("content-length")
64 if length_header == None:
65 """ The server did not provide a content-length header. """
66 length_header = -1
67 length = int(length_header)
68 print "Fetching ", str (round(float(length/1024),2)) , " kilobytes"
69 ret = ""
70 t_start = time.time()
71 while True:
72 t_delta = time.time() - t_start
73 if t_delta == 0:
74 t_delta = 1
75 if length_header != -1:
76 update_progress_bar( float(len(ret)) / length,
77 "%.2f K/s" % (len(ret) / 1024 / t_delta) )
78 tmp = fetcher.read(1024)
79 if len(tmp) == 0:
80 if len(ret) != length and length_header != -1:
81 raise Exception("Expected %s bytes, only received %s" % (
82 len(ret), length ))
83 print ""
84 return ret
85 ret += tmp
87 def write_to_a_text_file(file_loc, data):
88 f = open(file_loc, 'w')
89 f.write(data)
90 f.close()
92 def calculate_ipv4_subnet(host_count):
93 """ XXX: this will return incorrect values for anything above a /4
94 e.g. calculate_ipv4_subnet(536870912) will return 2 instead of 3
95 """
96 return 32 - int(ceil(log(host_count,2)))
98 def extract_data_from_gzip_file(gzip_file_loc, extract_file_loc):
99 gzip_file = gzip.open(gzip_file_loc, 'rb')
100 gunzipped_file = open(extract_file_loc, 'w')
101 while True:
102 gunzipped_data = gzip_file.read(1024)
103 if gunzipped_data == "":
104 break
105 gunzipped_file.writelines(gunzipped_data)
107 gzip_file.close()
108 gunzipped_file.close()
110 def read_data_from_binary_file(fname):
111 f = open(fname, 'rb')
112 data = f.read()
113 f.close()
114 return data
116 class Blockfinder(object):
118 def __init__(self, cache_dir, useragent, verbose=False):
119 self.cache_dir = cache_dir
120 self.useragent = useragent
121 self.cursor = None
122 self.conn = None
123 self.verbose = verbose
125 def create_blockfinder_cache_dir(self):
126 if not os.path.exists(self.cache_dir):
127 if self.verbose:
128 print "Initializing the cache directory..."
129 os.mkdir(self.cache_dir)
131 def cache_delegation(self, delegation_url):
132 """ Attempt to cache the contents of a delegation url in our cache dir. """
133 delegation = ""
134 print "Fetching " + delegation_url
135 delegation = fetch(delegation_url, self.useragent)
136 tmp = delegation_url.split('/')
137 delegation_file = str(self.cache_dir) + str(tmp[-1])
138 try:
139 write_to_a_text_file(delegation_file, delegation)
140 return True
141 except Exception, e:
142 print repr(e)
143 return False
145 def cache_is_dated(self, cached_files):
146 """ Returns True if the mtime of any files in cache dir is > 24hrs."""
147 try:
148 os.stat(self.cache_dir)
149 except OSError, e:
150 print "\nDid you initialize the cache directory?\n"
151 raise e
152 for file in cached_files:
153 fstat = os.stat(self.cache_dir + file)
154 if (time.time() - fstat.st_mtime) > 86400:
155 return True
156 return False
159 def connect_to_database(self):
160 self.conn = sqlite3.connect(self.cache_dir + "sqlitedb")
161 self.cursor = self.conn.cursor()
163 def commit_and_close_database(self):
164 self.conn.commit()
165 self.cursor.close()
167 def create_sql_database(self):
168 """ Creates a new sqlite database.
169 Existing delegation entries are dropped prior to inserting
170 'newer' delegations.
172 sql_script_comp = []
173 sql_script_comp.append("""drop table if exists delegations""" )
174 sql_script_comp.append("""create table delegations(registry text, cc text, start text, value INTEGER, date text, status text, type text)""")
175 sql_script_comp.append("""create table if not exists lir_record(cc text, start text, value INTEGER, type INTEGER)""")
176 self.cursor.executescript(";\n".join(sql_script_comp) + ";" )
177 self.conn.commit()
179 def insert_into_sql_database(self, delegations):
180 """ inserts delegation information into the sqlite database"""
181 rows = []
182 for delegation in delegations:
183 for entry in delegation:
184 registry = str(entry['registry'])
185 if not registry.isdigit() and str (entry['cc']) !="*":
186 temp_row = [entry['registry'], entry['cc'], entry['start'], \
187 entry['value'], entry['date'], entry['status'], entry['type']]
188 rows.append(temp_row)
190 text = """INSERT INTO delegations (registry, cc, start, value, date, status, type) VALUES (?,?,?,?,?,?,?)"""
191 self.cursor.executemany(text, rows)
192 self.conn.commit()
194 def get_total_delegations_from_db(self):
195 """ Returns the total count of the number of entries in the ipv4, ipv6 and asn table """
196 self.cursor.execute("""select count (*) from delegations""")
197 return int (self.cursor.fetchone()[0] )
199 def get_possible_match_entries(self, cc):
200 """ Get the count of 'possible' matching delegation entries"""
201 self.cursor.execute("""select count (*) from delegations where cc=?""", cc)
202 return int (self.cursor.fetchone()[0] )
204 def use_sql_database(self, request, cc):
205 """ Use the sqlite database that is created after fetching delegations
206 to output information for a given request """
207 if self.verbose:
208 print "We have %d entries in our delegation cache." % self.get_total_delegations_from_db()
209 text = "select start, value from delegations where type=? and cc=?"
210 cc = (cc,)
211 self.cursor.execute(text, (request, cc[0]) )
212 result = []
213 for row in self.cursor:
214 if request == "ipv4":
215 if Ipaddr:
216 first = Ipaddr.IPv4Address(str(row[0]))
217 last = Ipaddr.IPv4Address(int(first) + int(row[1]) - 1)
218 result += [str(x) for x in Ipaddr.summarize_address_range(first, last)]
219 else:
220 result.append(str(row[0]) + "/" + str(calculate_ipv4_subnet(int(row[1]))))
221 elif request == "ipv6":
222 result.append(str(row[0]) + "/" + str(int(row[1])))
223 else:
224 result.append(str(int(row[0])))
225 result.sort()
226 if self.verbose:
227 result.append("We found %d possible entries in our delegation cache." % self.get_possible_match_entries(cc) )
228 self.cursor.execute("""select count(*) from delegations where cc=? and type=?""", (cc[0], request) )
229 result.append("We found %d matching entries in our delegation cache." % int (self.cursor.fetchone()[0] ) )
230 return result
232 def get_md5_from_delegation_md5_file(self, delegation_file):
233 """ Returns the md5sum from the delegation md5 file
234 if it doesn't exist it returns an empty string"""
235 checksum = ""
236 try:
237 f = open(self.cache_dir + delegation_file + ".md5", "r")
238 checksum = f.read()
239 f.close()
240 if "=" in checksum:
241 pos = checksum.find("=") +2
242 checksum = str (checksum[pos:-1])
243 except Exception, e:
244 print repr(e)
245 return checksum
247 def verify_delegation_file(self, delegation_file):
248 """ compares the delegation file md5sum to that of the provided md5sum
249 returns True if they match otherwise returns False """
250 checksum = ""
251 checksum_of_file = ""
252 try:
253 data = read_data_from_binary_file(self.cache_dir + delegation_file)
254 checksum_of_file = str (hashlib.md5(data).hexdigest() )
255 except Exception, e:
256 print repr(e)
257 checksum = self.get_md5_from_delegation_md5_file(delegation_file)
258 if checksum != checksum_of_file:
259 return False
260 if checksum == checksum_of_file and checksum != "":
261 return True
262 return False
264 def verify_cache(self, delegation_files):
265 """ if in verbose mode prints the result of checking the checksum of the
266 delegation files """
267 for file in delegation_files:
268 if self.verbose:
269 print "verifying " + file
270 if self.verify_delegation_file(file):
271 if self.verbose:
272 print "the md5 checksum of " + file + " *matches* the provided checksum"
273 else:
274 if self.verbose:
275 print "the md5 checksum of " + file + " does *not* match the provided checksum"
277 def update_delegation_cache(self, delegation_urls):
278 """ Fetch multiple delegation urls and cache the contents. """
279 print "Updating delegation cache..."
281 for url in delegation_urls.split():
282 self.cache_delegation(url + ".md5")
283 if self.verify_delegation_file(url.rpartition('/')[-1]):
284 pass
285 else:
286 self.cache_delegation(url)
288 def update_lir_delegation_cache(self, delegation_urls):
289 """ Fetch multiple LIR delegation urls and cache the contents. """
290 print "Updating LIR delegation cache..."
291 for url in delegation_urls.split():
292 self.cache_delegation(url)
293 self.unpack_a_delegation_cache(delegation_urls, "LIR")
295 def unpack_a_delegation_cache(self, delegation_urls, del_type=""):
296 """ Unpack the fetched LIR delegation files into the blockfinder cache. """
297 # This probably should unlink the gzip'ed file if we care about space...
298 for url in delegation_urls.split():
299 gzip_filename = url.rpartition('/')[-1]
300 gunziped_filename = gzip_filename.rpartition('.')[0]
301 if self.verbose:
302 print "Unpacking " + del_type + "file " + gzip_filename + " into our cache as " + gunziped_filename
303 extract_data_from_gzip_file(self.cache_dir + gzip_filename, self.cache_dir + gunziped_filename)
305 def update_geoip_cache(self, geoip_urls):
306 """ Fetch country level resolution GeoIP files from a given url and cache
307 the contents. Unpack it if it's compressed. """
308 print "Updating GeoIP cache..."
309 for url in geoip_urls.split():
310 self.cache_delegation(url)
311 self.unpack_a_delegation_cache(geoip_urls, "GeoIP")
313 def load_delegation(self, delegation_file):
314 """ Load, parse and store the delegation file contents as a list. """
315 keys = "registry cc type start value date status"
316 try:
317 f = open(delegation_file, "r")
318 delegations = [ dict((k,v) for k,v in zip(keys.split(), line.split("|")))
319 for line in f.readlines() if not line.startswith("#")]
320 f.close()
321 return delegations
322 except OSError, e:
323 print repr(e)
325 def load_all_delegations(self, delegation_urls):
326 """ Load all delegations into memory. """
327 delegations = []
328 for url in delegation_urls.split():
329 filename = url.rpartition('/')[-1]
330 if self.verbose:
331 print "Attempting to load delegation file into memory: " + filename
332 delegations.append(self.load_delegation(self.cache_dir + filename))
333 return delegations
335 def download_country_code_file(self):
336 """ Download and save the latest opencountrycode TXT(';' - separated) file """
337 url = "http://www.iso.org/iso/list-en1-semic-3.txt"
338 text_content = urllib2.urlopen(url).read()
339 write_to_a_text_file(self.cache_dir + "countrycodes.txt", text_content)
341 def build_country_code_dictionary(self):
342 """ Return a dictionary mapping country name to the country code"""
343 map_co = {}
344 txt_file = str(self.cache_dir) + "countrycodes.txt"
345 for line in open(txt_file, 'r'):
346 line = line.replace("\n", "").replace("\r", "")
347 if line.startswith("This list states the country"):
348 continue
349 if line == "" or ";" not in line:
350 continue
351 name, code = line.split(";")
352 """ capitalize the individual parts of the country name """
353 name = ' '.join([part.capitalize() for part in name.split(" ")])
354 map_co[name] = code
355 return map_co
357 def get_name_from_country_code(self, cc_code):
358 map_co = self.build_country_code_dictionary()
359 country_name = [(key, value) for (key, value) in map_co.items() if value == cc_code]
360 if len(country_name) > 0:
361 return country_name[0][0]
363 def get_country_code_from_name(self, country_name):
364 """ Return the country code for a given country name. """
365 map_co = self.build_country_code_dictionary()
366 cc_code = [map_co[key] for key in map_co.keys() if key.upper().startswith(country_name.upper())]
367 if len(cc_code) > 0:
368 return cc_code[0]
370 def geoip_lookup(self, ip_addr):
371 # This would work with the CVS version of the GeoIP code
372 # However, MaxMind hasn't done a release in a long time.
373 # http://geoip.cvs.sourceforge.net/viewvc/geoip/python/test_v6.py?revision=1.1&view=markup
374 # gi = GeoIP.open(self.cache_dir + "GeoIPv6.dat",GeoIP.GEOIP_STANDARD)
375 # cc = gi.country_code_by_addr_v6(ip_addr)
376 # cc_name = gi.country_name_by_addr_v6(ip_addr)
377 gi = GeoIP.open(self.cache_dir + "GeoIP.dat",GeoIP.GEOIP_STANDARD)
378 cc = gi.country_code_by_addr(ip_addr)
379 cc_name = gi.country_name_by_addr(ip_addr)
380 return cc, cc_name
383 def rir_or_lir_lookup_ipv4(self, ip_addr, lookup_type):
384 ipv4arr = ip_addr.split('.')
385 result = []
386 if lookup_type == 'rir':
387 self.cursor.execute('select cc, start, value from delegations WHERE type="ipv4" and start LIKE ?', ( ipv4arr[0] + "." + ipv4arr[1] + ".%",))
388 else:
389 self.cursor.execute('select * from lir_record WHERE start LIKE ? and type=4', (ipv4arr[0] + "." + ipv4arr[1] + ".%",))
390 row = self.cursor.fetchone()
392 if row is None:
393 if lookup_type == "rir":
394 self.cursor.execute('select cc, start, value from delegations WHERE type="ipv4" and start LIKE ? ', (ipv4arr[0] + ".%",))
395 else:
396 self.cursor.execute('select * from lir_record WHERE start LIKE ? and type=4', (ipv4arr[0] + ".%",))
397 row = self.cursor.fetchone()
399 while(row is not None):
400 if (ip_address_to_dec(row[1]) <= ip_address_to_dec(ip_addr) < (ip_address_to_dec(row[1]) + row[2])):
401 result.append(row[0])
402 result.append(self.get_name_from_country_code(row[0]))
403 return result
404 row = self.cursor.fetchone()
406 def rir_lookup(self, ip_addr):
407 return self.rir_or_lir_lookup_ipv4(ip_addr, "rir")
409 def lir_lookup(self, ip_addr):
410 return self.rir_or_lir_lookup_ipv4(ip_addr, "lir")
412 def asn_lookup(self, asn):
413 self.cursor.execute('select cc from asn WHERE start LIKE ?', (asn,))
414 row = self.cursor.fetchone()
415 if row is not None:
416 print "AS country code: %s" % row[0]
417 print "AS country name: %s" % self.get_name_from_country_code(row[0])
418 else:
419 print "AS%s not found!" % asn
421 def rir_or_lir_lookup_ipv6(self, ip_addr, ip_query, type_q):
422 if type_q == "RIR":
423 self.cursor.execute("select cc, start, value from delegations where type='ipv6'and start like ?", (ip_query,) )
424 else:
425 self.cursor.execute("select cc, start, value from lir_record where type=6 and start like ?", (ip_query,) )
426 for row in self.cursor:
427 try:
428 if ip_addr in IPy.IP(row[1] + "/" + str(row[2])):
429 return row[0]
430 except ValueError, e:
431 if self.verbose:
432 print e
433 pass
435 def lookup_ipv6_address(self, ip_addr):
436 print "Reverse lookup for: " + ip_addr
437 split_addr = ip_addr.split(":")
438 for i in ["RIR", "LIR"]:
439 ip_query = ip_addr.split(":")[0] + ":" + ip_addr.split(":")[1] + "%"
440 result = self.rir_or_lir_lookup_ipv6(ip_addr, ip_query, i)
441 if result:
442 print i, "Country Name:", self.get_name_from_country_code(result)
443 else:
444 ip_query = ip_addr.split(":")[0] + ":%"
445 result = self.rir_or_lir_lookup_ipv6(ip_addr, ip_query, i)
446 if result:
447 print i, "Country Name:", self.get_name_from_country_code(result)
451 def lookup_ip_address(self, ip_addr):
452 """ Return the country code and name for a given ip address. Attempts to
453 use GeoIP if available."""
455 ip_addr = socket.getaddrinfo(ip_addr, 80)[0][4][0]
456 if IPy and IPy.IP(ip_addr).version() == 6:
457 self.lookup_ipv6_address(ip_addr)
458 return
460 if not ipv4_address_valid(ip_addr):
461 raise BlockFinderError('Invalid ip address!')
462 rir_cc = ""
463 print "Reverse lookup for: " + ip_addr
464 if GeoIP:
465 geoip_cc, geoip_cc_name = self.geoip_lookup(ip_addr)
466 print "GeoIP country code: " + str(geoip_cc)
467 print "GeoIP country name: " + str(geoip_cc_name)
469 rir = self.rir_lookup(ip_addr)
471 if rir:
472 rir_cc = rir[0]
473 print 'RIR country code:', rir[0]
474 print 'RIR country:', rir[1]
475 else:
476 print 'Not found in RIR db'
478 lir = self.lir_lookup(ip_addr)
479 if lir:
480 print 'LIR country code:', lir[0]
481 print 'LIR country :', lir[1]
483 if GeoIP:
484 if geoip_cc != rir_cc:
485 print "It appears that the RIR data conflicts with the GeoIP data"
486 print "The GeoIP data is likely closer to being correct due to " \
487 "sub-delegation issues with LIR databases"
489 def create_or_replace_lir_table_in_db(self):
490 self.cursor.execute("""drop table if exists lir_record """)
491 self.cursor.execute("""create table if not exists lir_record(cc text, start text, value INTEGER, type INTEGER)""")
492 self.conn.commit()
494 def extract_info_from_lir_file_and_insert_into_sqlite(self, filename):
495 block = []
496 country = ""
497 entry = False
498 insert_text = """insert into lir_record (cc, start, value, type) VALUES (?,?,?,?)"""
499 version = ""
500 for line in open(self.cache_dir + filename, "r"):
501 line = line.replace("\n", "")
502 if line == "":
503 entry = False
504 country, block, version = "", [], ""
505 elif not entry and "inetnum:" in line:
506 try:
507 line = line.replace("inetnum:", "").strip()
508 start_ip, num_ips = return_first_ip_and_number_in_inetnum(line)
509 block = [start_ip, num_ips]
510 entry = True
511 version = "4"
512 except Exception, e:
513 if self.verbose:
514 print repr(e), line
515 elif not entry and "inet6num:" in line:
516 try:
517 block = line.replace("inet6num:", "").strip().split("/")
518 entry = True
519 version = "6"
520 except Exception, e:
521 if self.verbose:
522 print repr(e), line
523 elif entry and "country:" in line:
524 country = line.replace("country:", "").strip()
525 data = (country, block[0], block[1], version )
526 self.cursor.execute(insert_text, data)
527 self.conn.commit()
529 def create_db_and_insert_delegation_into_db(self, delegation_urls):
530 self.create_sql_database()
531 delegations = self.load_all_delegations(delegation_urls)
532 self.insert_into_sql_database(delegations)
533 self.conn.commit()
535 def return_first_ip_and_number_in_inetnum(line):
536 start_ip = line.split("-")[0].strip()
537 end_ip = line.split("-")[1].strip()
538 num_ips = 1 + (ip_address_to_dec(end_ip) - ip_address_to_dec(start_ip) )
539 return start_ip, num_ips
541 def ip_address_to_dec(ip_addr):
542 ipar = ip_addr.split('.')
543 a = ['','','','']
544 for i in range(4):
545 a[i] = hex(int(ipar[i]))[2:]
546 if(int(ipar[i]) <= 15):
547 a[i] = """0""" + a[i]
549 total = '0x'+a[0]+a[1]+a[2]+a[3]
550 decimal = int(total,16)
551 return decimal
553 def ipv4_address_valid(ip_addr):
554 ipv4arr = ip_addr.split('.')
555 if len(ipv4arr) == 4:
556 for items in ipv4arr:
557 if int(items) > 255:
558 return False
559 return True
560 else:
561 return False
563 def main():
564 """ Where the magic starts. """
566 parser = OptionParser()
567 parser.add_option("-v", "--verbose", action="store_true", dest="verbose", \
568 help = "Be verbose", default=False)
570 parser.add_option("-c", "--cachedir", action="store", dest="cache_dir", \
571 help = "Set the cache directory", default= str(os.path.expanduser('~')) + "/.blockfinder/" )
573 parser.add_option("-u","--useragent", action="store", dest="useragent", \
574 help = "Provide a useragent which will be used when fetching delegation files" , \
575 default="Mozilla/5.0")
577 parser.add_option("-4", "--ipv4", action="store_true", dest="ipv4", \
578 help = "Search IPv4 allocations")
580 parser.add_option("-6", "--ipv6", action="store_true", dest="ipv6", \
581 help = "Search IPv6 allocations")
583 parser.add_option("-a", "--asn", action="store_true", dest="asn", \
584 help = "Search ASN allocations")
586 parser.add_option("-t", "--nation-state", action="store", dest="cc", \
587 help = "Set the country to search (given as a two-letter code)")
589 parser.add_option("-n", "--country-name", action="store", dest="country_name", \
590 help = "Set country to search (full name)")
592 parser.add_option("-x", "--hack-the-internet", action="store_true", dest="hack_the_internet", \
593 help = "Hack the internet")
595 parser.add_option("-r", "--reverse-lookup", action="store", dest="reverse_host", \
596 help = "Return the county name for the specified IP or hostname")
598 parser.add_option("-i", "--initialize-delegation", action="store_true", dest="init_del", \
599 help = "Initialize or update delegation information")
601 parser.add_option("-l", "--initialize-lir", action="store_true", dest="init_lir", \
602 help = "Initialize or update lir information")
604 parser.add_option("-d", "--reload-delegation", action="store_true", dest="reload_del", \
605 help = "Use existing delegation files to update the database")
607 parser.add_option("-z", "--reload-lir", action="store_true", dest="reload_lir", \
608 help = "Use existing lir files to update the database")
610 (options, args) = parser.parse_args()
611 country = None
612 verbose = options.verbose
613 useragent = options.useragent
614 cache_dir = options.cache_dir
616 block_f = Blockfinder(cache_dir, useragent, verbose)
618 requests = []
619 delegation_urls = """
620 ftp://ftp.arin.net/pub/stats/arin/delegated-arin-latest
621 ftp://ftp.ripe.net/ripe/stats/delegated-ripencc-latest
622 ftp://ftp.afrinic.net/pub/stats/afrinic/delegated-afrinic-latest
623 ftp://ftp.apnic.net/pub/stats/apnic/delegated-apnic-latest
624 ftp://ftp.lacnic.net/pub/stats/lacnic/delegated-lacnic-latest
626 geoip_country_urls = """http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
627 http://geolite.maxmind.com/download/geoip/database/GeoIPv6.dat.gz"""
629 lir_urls = """ftp://ftp.ripe.net/ripe/dbase/split/ripe.db.inetnum.gz
630 ftp://ftp.ripe.net/ripe/dbase/split/ripe.db.inet6num.gz"""
631 delegation_files = []
632 for url in delegation_urls.split():
633 filename = url.rpartition('/')
634 delegation_files.append(filename[-1])
636 block_f.create_blockfinder_cache_dir()
637 block_f.connect_to_database()
638 if not os.path.exists(cache_dir + "countrycodes.txt"):
639 try:
640 block_f.download_country_code_file()
641 except Exception, e:
642 print repr(e)
645 if options.hack_the_internet:
646 print "all your bases are belong to us!"
647 sys.exit(0)
648 if options.asn and options.reverse_host:
649 block_f.asn_lookup(options.reverse_host)
650 sys.exit(0)
652 if options.reverse_host:
653 block_f.lookup_ip_address(options.reverse_host)
654 sys.exit(0)
656 if options.ipv4:
657 requests.append("ipv4")
658 if options.ipv6:
659 requests.append("ipv6")
660 if options.asn:
661 requests.append("asn")
663 if options.cc:
664 country = options.cc.upper()
665 if options.country_name:
666 country = block_f.get_country_code_from_name(options.country_name)
668 if options.reload_del:
669 block_f.create_db_and_insert_delegation_into_db(delegation_urls)
670 sys.exit(0)
672 # Update and quit.
673 if options.init_del:
674 if GeoIP:
675 block_f.update_geoip_cache(geoip_country_urls)
676 block_f.update_delegation_cache(delegation_urls)
677 if verbose:
678 block_f.verify_cache(delegation_files)
679 block_f.create_db_and_insert_delegation_into_db(delegation_urls)
680 if not options.init_lir:
681 sys.exit(0)
682 if options.init_lir or options.reload_lir:
683 if options.init_lir:
684 block_f.update_lir_delegation_cache(lir_urls)
685 print "Extracting and inserting information from the lir files can take up to 5 minutes"
686 block_f.create_or_replace_lir_table_in_db()
687 for fname in "ripe.db.inetnum ripe.db.inet6num".split():
688 block_f.extract_info_from_lir_file_and_insert_into_sqlite(fname)
689 sys.exit(0)
691 if not requests:
692 print "Nothing to do. Have you requested anything?"
693 print "Example usage: blockfinder -v --ipv4 -t mm"
694 sys.exit(1)
696 if not country:
697 print "It appears your search did not match a country."
698 sys.exit(1)
699 # Check our cache age and warn if it's aged
700 if block_f.cache_is_dated(delegation_files) and verbose:
701 print "Your delegation cache is older than 24 hours; you probably want to update it."
702 if verbose:
703 print "Using country code: %s" % country
705 for request in requests:
706 try:
707 try:
708 print " \n".join(block_f.use_sql_database(request, country))
709 except sqlite3.Error, e:
710 print repr(e)
711 print "Please try reloading the database. (run ./blockfinder -i)."
712 except Exception, e:
713 print repr(e)
714 try:
715 block_f.cursor.close()
716 except Exception, e:
717 print repr(e)
719 if __name__ == "__main__":
720 main()