Ora supportiamo anche i nomi a dominio.

Leonardo [2010-05-19 16:03]
Ora supportiamo anche i nomi a dominio.
Filename
pywhoisd.conf
pywhoisd.db
pywhoisd.py
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...")


ViewGit