ip4addr2asn
authorGeorgios Kontaxis <redacted>
Tue, 10 Nov 2015 19:04:00 +0000 (14:04 -0500)
committerGeorgios Kontaxis <redacted>
Sun, 6 Dec 2015 03:03:12 +0000 (22:03 -0500)
Makefile [new file with mode: 0644]
README.md
get_asnmap.sh [new file with mode: 0644]
ip4addr2asn.py [new file with mode: 0755]
makedb.py [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..3051e34
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,10 @@
+.PHONY: all clean
+
+all: db.sqlite3
+
+db.sqlite3:
+       bash get_asnmap.sh
+       python makedb.py
+
+clean:
+       rm -i thyme_apnic_net* ip4net2asn.txt asn2name.txt db.sqlite3
index dda96c22eab2a90540860091fef3f7c1ca08947f..7d141aac6e047dafafffc95a710a5c4ff0e681a5 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1 +1,5 @@
 # ip4addr2asn
+
+```
+usage: ip4addr2asn.py ip4addr [ip4addr ...]
+```
diff --git a/get_asnmap.sh b/get_asnmap.sh
new file mode 100644 (file)
index 0000000..1e6a0bf
--- /dev/null
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+# http://thyme.apnic.net/
+
+tstamp=$(date +%Y%m%d);
+
+# Also current (jp), au, hk, london
+curl -L "http://thyme.apnic.net/us/data-raw-table" \
+       -o "thyme_apnic_net_us_net2asn_${tstamp}.txt" && \
+rm -f ip4net2asn.txt && \
+ln -s "thyme_apnic_net_us_net2asn_${tstamp}.txt" ip4net2asn.txt
+
+# Also current (jp), au, hk, london
+curl -L "http://thyme.apnic.net/hk/data-used-autnums" \
+       -o "thyme_apnic_net_us_asn2name_${tstamp}.txt" && \
+rm -f asn2name.txt && \
+ln -s "thyme_apnic_net_us_asn2name_${tstamp}.txt" asn2name.txt
diff --git a/ip4addr2asn.py b/ip4addr2asn.py
new file mode 100755 (executable)
index 0000000..60f8c82
--- /dev/null
@@ -0,0 +1,100 @@
+#!/usr/bin/python -u
+
+# kontaxis 2015-10-23
+
+from __future__ import print_function
+
+import os
+import sys
+import sqlite3
+
+# Prepare ip4masks
+ip4mask = [
+       0x00000000,
+       ((~0x0) << 31) & 0xffffffff, # /1
+       ((~0x0) << 30) & 0xffffffff, # /2
+       ((~0x0) << 29) & 0xffffffff, # /3
+       ((~0x0) << 28) & 0xffffffff, # /4
+       ((~0x0) << 27) & 0xffffffff, # /5
+       ((~0x0) << 26) & 0xffffffff, # /6
+       ((~0x0) << 25) & 0xffffffff, # /7
+       ((~0x0) << 24) & 0xffffffff, # /8
+       ((~0x0) << 23) & 0xffffffff, # /9
+       ((~0x0) << 22) & 0xffffffff, # /10
+       ((~0x0) << 21) & 0xffffffff, # /11
+       ((~0x0) << 20) & 0xffffffff, # /12
+       ((~0x0) << 19) & 0xffffffff, # /13
+       ((~0x0) << 18) & 0xffffffff, # /14
+       ((~0x0) << 17) & 0xffffffff, # /15
+       ((~0x0) << 16) & 0xffffffff, # /16
+       ((~0x0) << 15) & 0xffffffff, # /17
+       ((~0x0) << 14) & 0xffffffff, # /18
+       ((~0x0) << 13) & 0xffffffff, # /19
+       ((~0x0) << 12) & 0xffffffff, # /20
+       ((~0x0) << 11) & 0xffffffff, # /21
+       ((~0x0) << 10) & 0xffffffff, # /22
+       ((~0x0) <<  9) & 0xffffffff, # /23
+       ((~0x0) <<  8) & 0xffffffff, # /24
+       ((~0x0) <<  7) & 0xffffffff, # /25
+       ((~0x0) <<  6) & 0xffffffff, # /26
+       ((~0x0) <<  5) & 0xffffffff, # /27
+       ((~0x0) <<  4) & 0xffffffff, # /28
+       ((~0x0) <<  3) & 0xffffffff, # /29
+       ((~0x0) <<  2) & 0xffffffff, # /30
+       ((~0x0) <<  1) & 0xffffffff, # /31
+       ((~0x0) <<  0) & 0xffffffff  # /32
+]
+
+# Header
+print("%s | %s | %s | %s" % ("ASN".ljust(5), "IPv4 Address".ljust(15),
+       "BGP Prefix".ljust(18), "AS Name"))
+
+# Seperator
+print("%s | %s | %s | %s" % ("".ljust(5, "-"), "".ljust(15, "-"),
+       "".ljust(18, "-"), "".ljust(7, "-")))
+
+dirname = os.path.dirname(sys.argv[0])
+conn = sqlite3.connect(os.path.join(dirname, "db.sqlite3"))
+conn.text_factory = str
+c = conn.cursor()
+
+for arg in sys.argv[1:]:
+       ip4addr_s = arg
+
+       [x, y, z, w] = ip4addr_s.split(".")
+       ip4addr_i = (int(x) << 24) | (int(y) << 16) | (int(z) <<  8) | (int(w) <<  0)
+
+       # Test longer networks first.
+       hits = []
+       for i in range(32,0,-1):
+               net = "%u.%u.%u.%u/%u" % (
+                       ((ip4addr_i & ip4mask[i]) >> 24) & 0xff,
+                       ((ip4addr_i & ip4mask[i]) >> 16) & 0xff,
+                       ((ip4addr_i & ip4mask[i]) >>  8) & 0xff,
+                       ((ip4addr_i & ip4mask[i]) >>  0) & 0xff,
+                       i)
+
+               # Resolve an IPv4 address to an AS number.
+               c.execute('SELECT asn FROM ip4net2asn WHERE ip4net=?', (net,))
+               asn = c.fetchone()
+               if not asn:
+                       continue
+               asn = asn[0]
+               if asn in hits:
+                       continue
+               hits.append(asn)
+
+               # Resolve an AS number to a AS name.
+               asname = "NA"
+               c.execute('SELECT name FROM asn2name WHERE asn=?', (asn,))
+               name = c.fetchone()
+               if name:
+                       asname = name[0]
+
+               print("%s | %s | %s | %s" % (asn.ljust(5),
+                       ip4addr_s.ljust(15), net.ljust(18), asname))
+
+       # Always print something.
+       if not hits:
+               print("%s | %s | %s | %s" % ("NA".ljust(5), ip4addr_s.ljust(15),
+                       "NA".ljust(18), "NA"))
diff --git a/makedb.py b/makedb.py
new file mode 100644 (file)
index 0000000..ba0367e
--- /dev/null
+++ b/makedb.py
@@ -0,0 +1,65 @@
+#!/usr/bin/python -u
+
+from __future__ import print_function
+
+import os
+import sqlite3
+import sys
+import time
+
+dirname = os.path.dirname(sys.argv[0])
+
+# Populate ip4net2asn records array
+ip4net2asn = []
+
+# e.g., http://thyme.apnic.net/us/data-raw-table
+f = file(os.path.join(dirname, "ip4net2asn.txt"), "r")
+
+for line in f:
+       [ip4net, asn] = line.split("\t")
+       asn = asn.rstrip("\n")
+       ip4net2asn.append((ip4net, asn))
+
+f.close()
+
+# Populate asn2name records array
+asn2name = []
+
+# e.g., http://thyme.apnic.net/hk/data-used-autnums
+f = file(os.path.join(dirname, "asn2name.txt"), "r")
+
+for line in f:
+       asn = line[0:6].strip(" ")
+       name = line[6:].rstrip("\n")
+       asn2name.append((asn, name))
+
+f.close()
+
+# Make it happen
+conn = sqlite3.connect("db.sqlite3")
+conn.text_factory = str
+c = conn.cursor()
+
+# Create schema.
+c.execute("SELECT name FROM sqlite_master WHERE type='table' AND name=?",
+       ("last_generated",))
+match = c.fetchone()
+if not match:
+       c.execute("CREATE TABLE last_generated (epoch integer);")
+       c.execute("CREATE TABLE ip4net2asn (ip4net text unique, asn text);")
+       c.execute("CREATE INDEX ip4net on ip4net2asn (ip4net);")
+       c.execute("CREATE TABLE asn2name (asn text unique, name text);")
+       c.execute("CREATE INDEX asn on asn2name (asn);")
+
+c.execute('DELETE FROM last_generated');
+c.execute('INSERT INTO last_generated VALUES(?)',
+       (str(int(time.time())),))
+
+c.execute('DELETE FROM ip4net2asn');
+c.executemany('INSERT INTO ip4net2asn VALUES (?,?)', ip4net2asn)
+
+c.execute('DELETE FROM asn2name');
+c.executemany('INSERT INTO asn2name   VALUES (?,?)', asn2name)
+
+conn.commit()
+conn.close()
git clone https://git.99rst.org/PROJECT