class NetData: def __init__(self): self.ipcalc = IPCalc() self.asnum = ASNum() def revip(self, ip, af): if af == 4: t = ip.split(".") return "%s.%s.%s.%s" % (t[3], t[2], t[1], t[0]) elif af == 6: ip = ip.split("::")[0].split(":") ip.reverse() tmp = "" for i in ip: x = "%04X" % (int(i, 16)) tmp += x[::-1] rev = "" for i in range(0, len(tmp)): rev += "%s." % (tmp[i]) return rev[:-1] def get_origin(self, ip): af = self.ipcalc.af(ip) if af == 4: query = "%s.origin.asn.cymru.com" % (self.revip(ip, af)) elif af == 6: query = "%s.origin6.asn.cymru.com" % (self.revip(ip, af)) else: return None try: entry = dns.resolver.query(query, "TXT") except: return None for rdata in entry: data = str(rdata).replace("\"", "") t = data.split(" | ") return [t[0], t[1], t[2]] def get_subnet_asnum(self, ip): try: return self.get_origin(ip)[0].split(" ")[0] except: return None def get_asn_name(self, asn): query = "AS%s.asn.cymru.com" % (asn) try: entry = dns.resolver.query(query, "TXT") except: return "Unknown" for rdata in entry: data = str(rdata).replace("\"", "") try: return data.split(" | ")[4] except: return "Unknown" def query_whois(self, server, asnum): #return commands.getoutput("whois -h %s as%s" % (server, asnum)).split("\n") return "" def parse_whois_data(self, raw_whois_data): rirs = ["APNIC", "LACNIC", "AfriNIC", "RIPE", "ARIN"] data = "" in_aut_num = False in_role = False in_person = False for line in raw_whois_data: if len(line) == 0: in_aut_num = False in_role = False in_person = False if len(data) != 0 and data[-2:] != "\n\n": data += "\n" elif line.startswith("aut-num:"): in_aut_num = True elif line.startswith("ASNumber:"): in_aut_num = True elif line.startswith("OrgName:"): in_role = True elif line.startswith("OrgTechHandle:"): in_person = True elif line.startswith("OrgAbuseHandle:"): in_person = True elif line.startswith("role:"): is_rir = False for rir in rirs: if rir in line: is_rir = True if not is_rir: in_role = True elif line.startswith("person:"): in_person = True elif line.startswith("import:"): continue elif line.startswith("export:"): continue elif line.startswith("default:"): continue elif line.startswith("source:"): continue elif line.startswith("remarks:"): continue elif line.startswith("mp-import:"): continue elif line.startswith("mp-export:"): continue elif line.startswith("+"): continue elif line.startswith("\t"): continue elif line.startswith(" "): continue if in_aut_num: data += "%s\n" % (line) elif in_role: data += "%s\n" % (line) elif in_person: data += "%s\n" % (line) return data def get_whois_data(self, ip): try: (asn, net, country) = self.get_origin(ip) except: return (0, "UNKNOWN", "Unknown ASN", "0.0.0.0/0", "NL") asn_name = self.get_asn_name(asn) asn = asn.split()[0] (result, asn_obj) = self.asnum.get(asnum=asn) if not result: return (False, asn_obj) raw_whois_data = self.query_whois(asn_obj.rir.whois, asn) return (asn, asn_name, self.parse_whois_data(raw_whois_data), net, country)
class Subnet(BaseBackend): name = "Subnet" def __init__(self): BaseBackend.__init__(self, models.Subnet) self.ipcalc = IPCalc() self.asnum = ASNum() self.country = Country() self.rir = RIR() def has(self, *args, **kwargs): if "/" in kwargs['subnet']: kwargs['subnet'] = kwargs['subnet'].split("/")[0] subnet = self.ipcalc.dqtoi(kwargs['subnet']) return BaseBackend.has(self, subnet=subnet) def get(self, *args, **kwargs): if kwargs.has_key('subnet'): if "/" in kwargs['subnet']: kwargs['subnet'] = kwargs['subnet'].split("/")[0] subnet = self.ipcalc.dqtoi(kwargs['subnet']) return BaseBackend.get(self, subnet=subnet) else: return BaseBackend.get(self, *args, **kwargs) def contains(self, *args, **kwargs): ip = self.ipcalc.dqtoi(kwargs["ip"]) net = models.Subnet.objects.filter(subnet__lte=ip).filter(last__gte=ip) if net: return (True, net) else: return (False, "No network found for %s" % (kwargs["ip"])) def add(self, *args, **kwargs): if not "/" in kwargs['subnet']: return (False, "%s is not a subnet" % (kwargs['subnet'])) (net, mask) = kwargs['subnet'].split("/") asn = kwargs['asn'] af = self.ipcalc.af(kwargs['subnet']) (result, subnet) = self.get(subnet=net) if result: return (True, subnet) if kwargs['asn'] == 0: (result, rir) = self.rir.get(name="Unknown") if not result: return (False, rir) (result, country) = self.country.get(code=kwargs['cc']) if not result: return (False, country) (result, asnum) = self.asnum.get(asnum=kwargs['asn']) if not result: (result, asnum) = self.asnum.add(asnum=asn, name=kwargs['asn_name'], whois_data=kwargs['whois_data'], country=country, rir=rir) if not result: return (False, asnum) net_first=self.ipcalc.dqtoi(net) net_last = net_first + self.ipcalc.bittoip[int(mask)] subnet = models.Subnet( subnet=net_first, last=net_last, mask=int(mask), asnum=asnum, af=af, country=country, rir=asnum.rir, regdate=datetime.now() ) subnet.save() return (True, subnet) @transaction.commit_manually def bulk_import(self, import_data): t_start = mktime(datetime.now().timetuple()) data = [] failed = [] num_failed = 0 for entry in import_data: if entry[0] == "": num_failed += 1 failed.append(entry) continue (net, mask) = entry[0].split("/") tmp = {} tmp["subnet"] = self.ipcalc.dqtoi(net) tmp["mask"] = mask tmp["name"] = entry[1] try: tmp["asnum"] = models.ASNum.objects.filter(name=entry[2])[0] except: tmp["asnum"] = None data.append(tmp) for entry in data: subnet = models.Subnet( subnet=entry["subnet"], mask=entry["mask"], name=entry["name"], asnum=entry["asnum"], ) subnet.save() transaction.commit() reset_queries() t_end = mktime(datetime.now().timetuple()) return (t_end - t_start, num_failed, failed)
class NetData: def __init__(self): self.ipcalc = IPCalc() self.asnum = ASNum() def revip(self, ip, af): if af == 4: t = ip.split(".") return "%s.%s.%s.%s" % (t[3], t[2], t[1], t[0]) elif af == 6: ip = ip.split("::")[0].split(":") ip.reverse() tmp = "" for i in ip: x = "%04X" % (int(i, 16)) tmp += x[::-1] rev = "" for i in range(0, len(tmp)): rev += "%s." % (tmp[i]) return rev[:-1] def get_origin(self, ip): af = self.ipcalc.af(ip) if af == 4: query = "%s.origin.asn.cymru.com" % (self.revip(ip, af)) elif af == 6: query = "%s.origin6.asn.cymru.com" % (self.revip(ip, af)) else: return None try: entry = dns.resolver.query(query, "TXT") except: return None for rdata in entry: data = str(rdata).replace("\"", "") t = data.split(" | ") return [t[0], t[1], t[2]] def get_subnet_asnum(self, ip): try: return self.get_origin(ip)[0].split(" ")[0] except: return None def get_asn_name(self, asn): query = "AS%s.asn.cymru.com" % (asn) try: entry = dns.resolver.query(query, "TXT") except: return "Unknown" for rdata in entry: data = str(rdata).replace("\"", "") try: return data.split(" | ")[4] except: return "Unknown" def query_whois(self, server, asnum): #return commands.getoutput("whois -h %s as%s" % (server, asnum)).split("\n") return "" def parse_whois_data(self, raw_whois_data): rirs = ["APNIC", "LACNIC", "AfriNIC", "RIPE", "ARIN"] data = "" in_aut_num = False in_role = False in_person = False for line in raw_whois_data: if len(line) == 0: in_aut_num = False in_role = False in_person = False if len(data) != 0 and data[-2:] != "\n\n": data += "\n" elif line.startswith("aut-num:"): in_aut_num = True elif line.startswith("ASNumber:"): in_aut_num = True elif line.startswith("OrgName:"): in_role = True elif line.startswith("OrgTechHandle:"): in_person = True elif line.startswith("OrgAbuseHandle:"): in_person = True elif line.startswith("role:"): is_rir = False for rir in rirs: if rir in line: is_rir = True if not is_rir: in_role = True elif line.startswith("person:"): in_person = True elif line.startswith("import:"): continue elif line.startswith("export:"): continue elif line.startswith("default:"): continue elif line.startswith("source:"): continue elif line.startswith("remarks:"): continue elif line.startswith("mp-import:"): continue elif line.startswith("mp-export:"): continue elif line.startswith("+"): continue elif line.startswith("\t"): continue elif line.startswith(" "): continue if in_aut_num: data += "%s\n" % (line) elif in_role: data += "%s\n" % (line) elif in_person: data += "%s\n" % (line) return data def get_whois_data(self, ip): try: (asn, net, country) = self.get_origin(ip) except: return (0, "UNKNOWN", "Unknown ASN", "0.0.0.0/0", "NL") asn_name = self.get_asn_name(asn) asn = asn.split()[0] (result, asn_obj) = self.asnum.get(asnum=asn) if not result: return (False, asn_obj) raw_whois_data = self.query_whois(asn_obj.rir.whois, asn) return (asn, asn_name, self.parse_whois_data(raw_whois_data), net, country)
class IP(BaseBackend): name = "IP" def __init__(self): BaseBackend.__init__(self, models.IP) self.netdata = NetData() self.ipcalc = IPCalc() self.subnet = Subnet() def has(self, *args, **kwargs): (dq, mask) = self.ipcalc.parse_addr(kwargs['ip']) ip = self.ipcalc.dqtoi(dq) return BaseBackend.has(self, ip=ip, mask=mask) def get(self, *args, **kwargs): (dq, mask) = self.ipcalc.parse_addr(kwargs['ip']) ip = self.ipcalc.dqtoi(dq) return BaseBackend.get(self, *args, ip=ip) def add(self, *args, **kwargs): af = self.ipcalc.af(kwargs['ip']) if not af in [4, 6]: return (False, "No AF found for %s" % (ip)) if "/" in kwargs['ip']: (ip, mask) = kwargs['ip'].split('/') first = self.ipcalc.dqtoi(ip) last = first + self.ipcalc.size(kwargs['ip']) else: ip = kwargs['ip'] if af == 4: mask = 32 elif af == 6: mask = 128 first = self.ipcalc.dqtoi(ip) last = first if self.has(ip=ip, mask=mask): return (True, self.get(ip=ip, mask=mask)) try: (asn, asn_name, whois_data, net, cc) = self.netdata.get_whois_data(kwargs["ip"]) except ValueError: return (False, "Cannot fetch whois data") if net == "0.0.0.0/0": net = None else: if not self.subnet.has(subnet=net): (result, net) = self.subnet.add(subnet=net, asn=asn, asn_name=asn_name, whois_data=whois_data, cc=cc) if not result: return (False, net) else: (result, net) = self.subnet.get(subnet=net) if not result: return (False, net) ip = models.IP(ip=first, mask=mask, last=last, subnet=net, af=af) ip.save() return (True, ip)
class IP(BaseBackend): name = "IP" def __init__(self): BaseBackend.__init__(self, models.IP) self.netdata = NetData() self.ipcalc = IPCalc() self.subnet = Subnet() def has(self, *args, **kwargs): (dq, mask) = self.ipcalc.parse_addr(kwargs['ip']) ip = self.ipcalc.dqtoi(dq) return BaseBackend.has(self, ip=ip, mask=mask) def get(self, *args, **kwargs): (dq , mask) = self.ipcalc.parse_addr(kwargs['ip']) ip = self.ipcalc.dqtoi(dq) return BaseBackend.get(self, *args, ip=ip) def add(self, *args, **kwargs): af = self.ipcalc.af(kwargs['ip']) if not af in [4,6]: return (False, "No AF found for %s" % (ip)) if "/" in kwargs['ip']: (ip, mask) = kwargs['ip'].split('/') first = self.ipcalc.dqtoi(ip) last=first + self.ipcalc.size(kwargs['ip']) else: ip = kwargs['ip'] if af == 4: mask = 32 elif af == 6: mask = 128 first = self.ipcalc.dqtoi(ip) last = first if self.has(ip=ip, mask=mask): return (True, self.get(ip=ip, mask=mask)) try: (asn, asn_name, whois_data, net, cc) = self.netdata.get_whois_data(kwargs["ip"]) except ValueError: return (False, "Cannot fetch whois data") if net == "0.0.0.0/0": net = None else: if not self.subnet.has(subnet=net): (result, net) = self.subnet.add(subnet=net, asn=asn, asn_name=asn_name, whois_data=whois_data, cc=cc) if not result: return (False, net) else: (result, net) = self.subnet.get(subnet=net) if not result: return (False, net) ip = models.IP( ip=first, mask=mask, last=last, subnet=net, af=af ) ip.save() return (True, ip)