diff --git a/pywhoisd.conf b/pywhoisd.conf
index b3b8f8b..2ab6977 100644
--- a/pywhoisd.conf
+++ b/pywhoisd.conf
@@ -11,7 +11,8 @@ config_file = pywhoisd.db;
# This sets the welcome banner that will be displayed to user
# contacting us on port 43
-welcome_banner = This is the whoisd server for the GNet autonomous network.
- If you'd like to become part of out network visit us
- at http://linus.robol.it/gnet/ or (if you have access now)
- http://linus.leo.gnet/gnet/. See you soon!;
\ No newline at end of file
+welcome_banner = This is the whoisd server for the GNet
+ autonomous network. If you'd like to become part
+ of our network visit us at http://linus.robol.it/gnet/
+ or (if you have access now) http://linus.leo.gnet/gnet/.
+ See you soon!;
\ No newline at end of file
diff --git a/pywhoisd.db b/pywhoisd.db
index 4d82709..8eb7c14 100644
--- a/pywhoisd.db
+++ b/pywhoisd.db
@@ -30,5 +30,40 @@ net 6.15.1.0/24 {
name = Lawvere net;
owner = Giorgio Mossa <mossa@ineff.gnet>;
ns = 6.20.10.1;
- ciao = pirla;
+};
+
+net 6.11.1.0/24 {
+ name = Freschi GNet;
+ owner = Luca Freschi <l.freschi@yahoo.it>;
+ ns = 6.20.10.1;
+};
+
+net 6.0.0.0/8 {
+ name = GNET;
+ owner = undefined;
+ ns = 6.20.10.1, 6.22.22.22;
+};
+
+domain leo.gnet {
+ name = Leo Gnet;
+ owner = Leonardo Robol <leo@robol.it>;
+ ns = 6.20.10.1;
+};
+
+domain ineff.gnet {
+ name = Ineff Gnet;
+ owner = Giorgio Mossa <mossa@ineff.gnet>;
+ ns = 6.20.10.1;
+};
+
+domain lf.gnet {
+ name = Luca GNet;
+ owner = Luca Freschi <l.freschi@yahoo.it>;
+ ns = 6.20.10.1;
+};
+
+domain gnet {
+ name = GNET;
+ owner = Undefined;
+ ns = 6.20.10.1, 6.22.22.22;
};
\ No newline at end of file
diff --git a/pywhoisd.py b/pywhoisd.py
index 142d6ec..93befc7 100755
--- a/pywhoisd.py
+++ b/pywhoisd.py
@@ -5,34 +5,28 @@
# provide a basic whois for GNet.
#
-import SocketServer, re, math
+import SocketServer, re, math, syslog
from ipcalc import IP, Network
+# Dictionaries that will contain runtime data
+# for the server
ip_database = {}
domain_database = {}
config = {}
-def ip_in_subnet(ip, network, subnet):
- ip = map(int, ip.split("."))
- network = map(int, network.split("."))
- if "." in subnet:
- subnet = map(int, subnet.split("."))
- subnet = map(lambda x: 255 - x, subnet)
- subnet = math.log(subnet[3] + subnet[2] * 256 + subnet[1] * pow(256,2) + subnet[0] * pow(256,3), 2)
- subnet = pow(2, 32 - int(subnet))
- ip = ip[3] + ip[2] * 256 + ip[1] * pow(256,2) + ip[0] * pow(256,3)
- network = network[3] + network[2] * 256 + network[1] * pow(256,2) + network[0]*pow(256,3)
- if ((ip - network) < subnet) and (ip-network >= 0):
- return True
- else:
- return False
+def Log(message):
+ print message
+ syslog.syslog (message)
def get_net_of_ip(ip):
+ """
+ Get network in which the given ip is
+ """
interesting_networks = []
for (address, net) in ip_database.items():
if IP(ip) in Network(address):
interesting_networks.append (address)
- return address
+ return interesting_networks
def format_output(field, value):
"""
@@ -43,17 +37,24 @@ def format_output(field, value):
return " "*4 + output
def format_message(message):
+ """
+ Normal message of the server
+ """
output = "\n"
for line in message.split("\n"):
line = line.strip()
- output += """\n %% """ + line.ljust(85) + """ %%"""
+ output += """\n %% """ + line.ljust(65) + """ %%"""
return output + "\n\n"
def resolve_ip(ip):
+ """
+ Resolve an ip: it search all the data that match it
+ """
output = ""
nets = get_net_of_ip(ip)
for net in nets:
output += format_message("GNet whoisd answering for ip %s" % ip)
+ output += format_output ("Range", net)
net = ip_database[net]
if net.name is not None:
output += format_output ("Name", net.name)
@@ -66,14 +67,46 @@ def resolve_ip(ip):
for k, v in net.data.items():
output += format_output (k.capitalize(),v)
if len(nets) == 0:
+
output = format_message("IP %s not found\n" % ip)
- output += format_message("Bye")
return output
+def get_domains_of_name(domain):
+ interesting_domains = []
+ for domain_name, domain_data in domain_database.items():
+ if domain.endswith(domain_name):
+ interesting_domains.append (domain_name)
+
+ return interesting_domains
+
def resolve_domain(domain):
- return format_message("Feature not yet implemented")
+ """
+ Resolve a domain. It is not yet implemented
+ """
+ output = ""
+ domains = get_domains_of_name(domain)
+ for d in domains:
+ output += format_message("GNet whoisd answering for domain %s" % d)
+ output += format_output ("Domain", d)
+ domain = domain_database[d]
+ if domain.name is not None:
+ output += format_output ("Name", domain.name)
+ if domain.owner is not None:
+ output += format_output ("Owner", domain.owner)
+ if domain.ns is not None:
+ output += format_output ("Nameserver", domain.ns)
+ if len(domain.data.items()) > 0:
+ output += format_message("Additional data")
+ for k, v in domain.data.items():
+ output += format_output (k.capitalize(),v)
+ if len(domains) == 0:
+ return format_message("No domain found for %s" % domain)
+ return output
def hello():
+ """
+ Say hello, server!
+ """
if config.has_key('welcome_banner'):
return config['welcome_banner']
else:
@@ -93,38 +126,50 @@ class WhoisRequestHandler(SocketServer.StreamRequestHandler):
request = self.rfile.readline().strip()
if re.search(r"\d+\.\d+\.\d+\.\d+", request.strip()):
- try:
- response += resolve_ip(request.split("/")[0])
- except Exception, e:
- response = format_message("An error occured while processing the request, aborting.\n%s" % e)
+ response += resolve_ip(request.split("/")[0])
else:
response += resolve_domain(request)
+ response += format_message("Bye")
self.request.send (response)
return
class Net():
-
+ #
+ # Net is a class representing the network
+ # contained in the local database and the
+ # net obtained from other whois server.
+ #
+ # It act as a C struct containing only the
+ # data and no method.
def __init__(self, name, owner, ns, data):
self.name = name
self.owner = owner
self.ns = ns
self.data = data
+class Domain():
+ #
+ #
+ #
+ def __init__(self, name, owner, ns, data):
+ self.name, self.owner, self.ns = name, owner, ns
+ self.data = data
+
def populate_databases(config_file):
"""
Populate databases with the data of our zones
"""
- print "Populating database"
+ Log ("Populating database with entry in %s" % config_file)
try:
f = open(config_file, 'r')
- data = f.read()
+ config_data = f.read()
except IOError:
- print >>stderr, "Error while loading config file. exiting"
+ Log ("Error while loading config file. exiting")
- nets = re.findall (r"net\s+(\d+\.\d+\.\d+\.\d+[/\d]*)[\s|\n]+\{([^\}]+)\};", data)
+ nets = re.findall (r"net\s+(\d+\.\d+\.\d+\.\d+[/\d]*)[\s|\n]+\{([^\}]+)\};", config_data)
for net in nets:
- print "> net %s loaded" % net[0]
+ Log ("Loading net %s" % net[0])
fields = re.findall(r"(\w+)\s*=\s*([^;]+);", net[1])
name, owner, ns = None, None, None
data = {}
@@ -140,14 +185,42 @@ def populate_databases(config_file):
ip_database[net[0]] = Net(name = name, owner = owner, ns = ns,
data = data)
-def parse_config_file(config_file):
+ domains = re.findall(r"domain\s+([^\s]+)[\s|\n]+\{([^\}]+)\};", config_data)
+ for domain in domains:
+ Log ("Loading domain %s" % domain[0])
+ fields = re.findall(r"(\w+)\s*=\s*([^;]+);", domain[1])
+ name, owner, ns = None, None, None
+ data = {}
+ for field, value in fields:
+ if field.lower() == 'name':
+ name = value.strip()
+ elif field.lower() == 'owner':
+ owner = value.strip()
+ elif field.lower() == 'ns':
+ ns = value.strip()
+ else:
+ data[field] = value
+ domain_database[domain[0]] = Domain(name = name, owner = owner, ns = ns,
+ data = data)
+
+def parse_config_file(config_file):
+ """
+ Parse config file and load_data into memory
+ """
config = {}
f = open(config_file, 'r')
content = f.read()
f.close()
for (key, value) in re.findall(r"([^\s]+)\s*=\s*([^;]+)\s*;", content):
- config[key] = value
+ # Gestiamo in maniera particolare
+ # i campi che mi forniscono un array.
+ if key == "master_domains":
+ config[key] = []
+ for domain in eval(value):
+ config[key].append(domain)
+ else:
+ config[key] = value
return config
@@ -157,13 +230,13 @@ if __name__ == "__main__":
config = parse_config_file ('pywhoisd.conf')
populate_databases(config['config_file'])
- host, port = "localhost", 43
- server = SocketServer.TCPServer((host, port), WhoisRequestHandler)
+ host, port = "0.0.0.0", 43
+ server = SocketServer.ThreadingTCPServer((host, port), WhoisRequestHandler)
+ server.allow_reuse_address = True
try:
server.serve_forever(0.1)
except KeyboardInterrupt:
- print "Exiting...",
- print "done"
+ Log ("Exiting...")