def test_ipv4_unicode(): # Fully qualified assert unicode(IPv4("192.168.0.0/24")), u"192.168.0.0/24" # Address only assert unicode(IPv4("192.168.0.0")), u"192.168.0.0/32" # Netmask assert unicode(IPv4("192.168.0.0", netmask="255.255.255.0")) == u"192.168.0.0/24"
def test_ipv4_sub(): # prefix - number returns prefix assert repr(IPv4("192.168.0.10/32") - 9) == "<IPv4 192.168.0.1/32>" assert repr(IPv4("192.168.1.10/32") - 265) == "<IPv4 192.168.0.1/32>" assert repr(IPv4("0.0.0.0/32") - 1) == "<IPv4 255.255.255.255/32>" # prefix - prefix returns distance assert IPv4("192.168.0.10/32") - IPv4("192.168.0.1/32") == 9
def test_ipv4_comparison(p1, p2, c, eq, ne, lt, le, gt, ge): p1 = IPv4(p1) p2 = IPv4(p2) assert ((p1 > p2) - (p1 < p2)) == c assert (p1 == p2) is eq assert (p1 != p2) is ne assert (p1 < p2) is lt assert (p1 > p2) is gt assert (p1 <= p2) is le assert (p1 >= p2) is ge
def test_ipv4_iter_cover(): assert [repr(x) for x in IPv4("192.168.0.0/24").iter_cover(23)] == [] assert [repr(x) for x in IPv4("192.168.0.0/24").iter_cover(24)] == ["<IPv4 192.168.0.0/24>"] assert [repr(x) for x in IPv4("192.168.0.0/23").iter_cover(24)] == [ "<IPv4 192.168.0.0/24>", "<IPv4 192.168.1.0/24>" ] assert [repr(x) for x in IPv4("192.168.0.0/22").iter_cover(24)] == [ "<IPv4 192.168.0.0/24>", "<IPv4 192.168.1.0/24>", "<IPv4 192.168.2.0/24>", "<IPv4 192.168.3.0/24>" ]
def test_ipv4_hash(): p0 = IPv4("192.168.0.1") p1 = IPv4("192.168.0.2") s = {p0} assert p0 in s assert p1 not in s ss = {p0: 1} assert ss[p0] == 1 with pytest.raises(KeyError): ss[p1]
def test_ipv4_hash(p1, p2): p1 = IPv4(p1) p2 = IPv4(p2) s = {p1} assert p1 in s assert p2 not in s ss = {p1: 1} assert ss[p1] == 1 with pytest.raises(KeyError): ss[p2] # pylint: disable=pointless-statement
def test_ipv4_hash(p1, p2): p1 = IPv4(p1) p2 = IPv4(p2) s = {p1} assert p1 in s assert p2 not in s ss = {p1: 1} assert ss[p1] == 1 with pytest.raises(KeyError): ss[p2]
def test_ipv4_comparison(ipv4_comparison): p1, p2, c, eq, ne, lt, le, gt, ge = ipv4_comparison p1 = IPv4(p1) p2 = IPv4(p2) assert cmp(p1, p2) is c assert (p1 == p2) is eq assert (p1 != p2) is ne assert (p1 < p2) is lt assert (p1 > p2) is gt assert (p1 <= p2) is le assert (p1 >= p2) is ge
def test_ipv4_iter_address(): assert [repr(x) for x in IPv4("192.168.0.0").iter_address(count=5)] == [ "<IPv4 192.168.0.0/32>", "<IPv4 192.168.0.1/32>", "<IPv4 192.168.0.2/32>", "<IPv4 192.168.0.3/32>", "<IPv4 192.168.0.4/32>" ] assert [repr(x) for x in IPv4("192.168.0.255").iter_address(count=5)] == [ "<IPv4 192.168.0.255/32>", "<IPv4 192.168.1.0/32>", "<IPv4 192.168.1.1/32>", "<IPv4 192.168.1.2/32>", "<IPv4 192.168.1.3/32>" ] assert [repr(x) for x in IPv4("192.168.0.255").iter_address(until="192.168.1.3")] == [ "<IPv4 192.168.0.255/32>", "<IPv4 192.168.1.0/32>", "<IPv4 192.168.1.1/32>", "<IPv4 192.168.1.2/32>", "<IPv4 192.168.1.3/32>" ]
def test_prefixdb_ipv4(): db = PrefixDB() db[IPv4("192.168.0.0/24")] = 1 db[IPv4("192.168.1.0/24")] = 2 db[IPv4("192.168.2.0/24")] = 3 db[IPv4("10.0.0.0/8")] = 4 assert db[IPv4("192.168.0.0/24")] == 1 assert db[IPv4("192.168.1.0/24")] == 2 assert db[IPv4("192.168.2.0/24")] == 3 assert db[IPv4("10.0.0.0/8")] == 4 with pytest.raises(KeyError): db[IPv4("172.16.0.0/12")]
def test_prefixdb_ipv4(p1, p2, p3, p4, p5, p6, p7, p8, p9): db = PrefixDB() db[IPv4(p1)] = p2 db[IPv4(p3)] = p4 db[IPv4(p5)] = p6 db[IPv4(p7)] = p8 assert db[IPv4(p1)] == p2 assert db[IPv4(p3)] == p4 assert db[IPv4(p5)] == p6 assert db[IPv4(p7)] == p8 with pytest.raises(KeyError): db[IPv4(p9)]
def upload_axfr(data): p = IP.prefix(prefix.prefix) count = 0 for row in data: row = row.strip() if row == "" or row.startswith(";"): continue row = row.split() if len(row) != 5 or row[2] != "IN" or row[3] != "PTR": continue if row[3] == "PTR": # @todo: IPv6 x = row[0].split(".") ip = "%s.%s.%s.%s" % (x[3], x[2], x[1], x[0]) fqdn = row[4] if fqdn.endswith("."): fqdn = fqdn[:-1] # Leave only addresses residing into "prefix" # To prevent uploading to not-owned blocks if not p.contains(IPv4(ip)): continue a, changed = Address.objects.get_or_create(vrf=vrf, afi=afi, address=ip) if a.fqdn != fqdn: a.fqdn = fqdn changed = True if changed: a.save() count += 1 return count
def execute_cli(self, **kwargs): iface = [] cmd = self.scripts.get_chassis_id() mac = cmd[0]["first_chassis_mac"] self.cli("4") # Enter Configuration menu cmd = self.cli("1") # Enter Network submenu match = self.rx_ipaddr.search(cmd) ipaddr = match.group("ip") match = self.rx_mask.search(cmd) # netmask may be wrong when DHCP is used! mask = match.group("mask") ip = IPv4(ipaddr, mask) iface += [{ "name": "mgmt", "admin_status": True, "oper_status": True, "type": "management", "mac": mac, "subinterfaces": [{ "name": "mgmt", "enabled_afi": ["IPv4"], "mac": mac, "ipv4_addresses": [ip], "admin_status": True, "oper_status": True, }], }] iface += self.get_phys_ports() return [{"interfaces": iface}]
def execute_snmp(self, **kwargs): cmd = self.scripts.get_chassis_id() mac = cmd[0]["first_chassis_mac"] ipaddr = self.snmp.get( "1.3.6.1.4.1.32108.1.7.4.1.1.0") # PLANAR-sdo3002-MIB::currentIP # netmask may be wrong when DHCP is used! mask = self.snmp.get("1.3.6.1.4.1.32108.1.7.4.1.4.0" ) # PLANAR-sdo3002-MIB::staticSubnetMask ip = IPv4(ipaddr, mask) ifaces = [{ "name": "mgmt", "admin_status": True, "oper_status": True, "type": "management", "mac": mac, "subinterfaces": [{ "name": "mgmt", "enabled_afi": ["IPv4"], "mac": mac, "ipv4_addresses": [ip], "admin_status": True, "oper_status": True, }], }] ifaces += self.get_phys_ports() return [{"interfaces": ifaces}]
def on_ipv4_route(self, tokens): """ ip route-static 0.0.0.0 0.0.0.0 172.20.66.30 preference 30 @todo ip route-static 10.10.10.0 255.255.254.0 Vlanif7 10.10.100.1 ip route-static vpn-instance vpn1 1.1.1.1 255.255.255.255 10.10.10.10 """ if tokens[2] == "vpn-instance": p = IPv4(tokens[4], netmask=tokens[5]) nh = tokens[6] else: p = IPv4(tokens[2], netmask=tokens[3]) nh = tokens[4] sf = self.get_static_route_fact(str(p)) # rest = tokens[3].split() # nh = rest.pop(0) if is_ipv4(nh): sf.next_hop = nh
def on_interface_address(self, tokens): ip = str(IPv4(tokens[0], netmask=tokens[1])) si = self.get_current_subinterface() if len(tokens) > 2 and tokens[2] == "secondary": si.ipv4_addresses += [ip] else: si.ipv4_addresses = [ip] + si.ipv4_addresses si.add_afi("IPv4")
def wildcard(self): """ Returns Cisco wildcard for IPv4 :return: """ if self.is_ipv4: return IPv4(self.prefix).wildcard.address return ""
def get_vpn_id(ip): try: return vpn_db[IPv4(ip)] except KeyError: pass if self.object.vrf: return self.object.vrf.vpn_id return GLOBAL_VRF
def size(self): """ Returns IPv4 prefix size :return: """ if self.is_ipv4: return IPv4(self.prefix).size return None
def netmask(self): """ returns Netmask for IPv4 :return: """ if self.is_ipv4: return IPv4(self.prefix).netmask.address return None
def broadcast(self): """ Returns Broadcast for IPv4 :return: """ if self.is_ipv4: return IPv4(self.prefix).last.address return None
def convert_prefix(self, prefix): """ Convert ip prefix to the format accepted by router's CLI """ if "/" in prefix and self.requires_netmask_conversion: prefix = IPv4(prefix) return "%s %s" % (prefix.address, prefix.netmask.address) return prefix
def get_ipaddr(self, name): try: v = self.cli("show interface " + name) except self.CLISyntaxError: return match = self.rx_ip.match(v) if match: return [IPv4(match.group("ip"), netmask=match.group("mask")).prefix]
def to_prefix(self, address, netmask): """ Convert address and netmask to prefix form :param address: :param netmask: :return: """ return IPv4(address, netmask=netmask).prefix
def execute_cli(self): r = [] subs = defaultdict(list) v = self.cli("show ip", cached=True).strip() for match in self.rx_iface.finditer(v): num = None iface_name = match.group("name").split("@")[0] i_type = self.INTERFACE_TYPES.get(match.group("type"), "other") s = { "name": iface_name, "admin_status": "LOWER_UP" in match.group("status"), "oper_status": "UP" in match.group("status"), "type": i_type, "mac": match.group("mac"), "enabled_protocols": [], } if "." in iface_name: iface_name, num = iface_name.rsplit(".", 1) if num: if int(num) < 4000: s["vlan_ids"] = num if match.group("inet_ip"): s["ipv4_addresses"] = [IPv4(match.group("inet_ip"))] s["enabled_afi"] = ["IPv4"] subs[iface_name] += [s.copy()] # sub = {"subinterfaces": [i.copy()]} r += [{ "name": iface_name, "admin_status": "LOWER_UP" in match.group("status"), "oper_status": "UP" in match.group("status"), "type": i_type, "mac": match.group("mac"), "enabled_protocols": [], }] for l in r: if l["name"] in subs: l["subinterfaces"] = subs[l["name"]] else: l["subinterfaces"] = [{ "name": l["name"], "description": l.get("description", ""), "type": "SVI", "enabled_afi": ["BRIDGE"] if l["type"] in ["physical", "aggregated"] else [], "admin_status": l["admin_status"], "oper_status": l["oper_status"], "snmp_ifindex": l["snmp_ifindex"], }] return [{"interfaces": r}]
def test_ipv4_area_spot(): assert [repr(x) for x in IPv4("192.168.0.0/24").area_spot([], dist=2)] == [] assert [repr(x) for x in IPv4("192.168.0.0/24").area_spot([], dist=2, sep=True)] == [] assert [repr(x) for x in IPv4("192.168.0.0/30").area_spot(["192.168.0.1"], dist=16, sep=True) ] == ["<IPv4 192.168.0.1/32>", "<IPv4 192.168.0.2/32>"] assert [ repr(x) for x in IPv4("192.168.0.0/24") .area_spot(["192.168.0.1", "192.168.0.2", "192.168.0.128"], dist=2) ] == [ "<IPv4 192.168.0.1/32>", "<IPv4 192.168.0.2/32>", "<IPv4 192.168.0.3/32>", "<IPv4 192.168.0.4/32>", "<IPv4 192.168.0.126/32>", "<IPv4 192.168.0.127/32>", "<IPv4 192.168.0.128/32>", "<IPv4 192.168.0.129/32>", "<IPv4 192.168.0.130/32>" ] assert [ repr(x) for x in IPv4("192.168.0.0/24") .area_spot(["192.168.0.1", "192.168.0.2", "192.168.0.128"], dist=2, sep=True) ] == [ "<IPv4 192.168.0.1/32>", "<IPv4 192.168.0.2/32>", "<IPv4 192.168.0.3/32>", "<IPv4 192.168.0.4/32>", "None", "<IPv4 192.168.0.126/32>", "<IPv4 192.168.0.127/32>", "<IPv4 192.168.0.128/32>", "<IPv4 192.168.0.129/32>", "<IPv4 192.168.0.130/32>" ] assert [ repr(x) for x in IPv4("192.168.0.0/24") .area_spot(["192.168.0.1", "192.168.0.254"], dist=2, sep=True) ] == [ "<IPv4 192.168.0.1/32>", "<IPv4 192.168.0.2/32>", "<IPv4 192.168.0.3/32>", "None", "<IPv4 192.168.0.252/32>", "<IPv4 192.168.0.253/32>", "<IPv4 192.168.0.254/32>" ] assert [repr(x) for x in IPv4("192.168.0.0/31") .area_spot(["192.168.0.1"], dist=2, sep=True)] == ["<IPv4 192.168.0.1/32>"]
def test_ipv4_in(): assert "192.168.0.0/24" in IPv4("192.168.0.0/24") assert IPv4("192.168.0.0/24") in IPv4("192.168.0.0/24") assert "192.168.1.1" not in IPv4("192.168.0.0/24") assert IPv4("192.168.1.1") not in IPv4("192.168.0.0/24") with pytest.raises(ValueError): "::1" in IPv4("192.168.0.0/24")
def usage(self): if self.is_ipv4: usage = getattr(self, "_usage_cache", None) if usage is not None: # Use update_prefixes_usage results return usage size = IPv4(self.prefix).size if not size: return 100.0 n_ips = Address.objects.filter(prefix=self).count() if n_ips and size > 2 and self.effective_prefix_special_address == "X": # Exclude special addresses size -= len(IPv4(self.prefix).special_addresses) n_pfx = sum( IPv4(p).size for p in Prefix.objects.filter(parent=self).only( "prefix").values_list("prefix", flat=True)) return float(n_ips + n_pfx) * 100.0 / float(size) return None
def on_static_route(self, tokens): """ ip default-gateway 1.2.5.9 :param tokens: """ # print tokens if tokens[2] == "default-gateway": prefix = IPv4("0.0.0.0", netmask="0.0.0.0") self.get_static_route_fact(str(prefix)).next_hop = tokens[-1]
def usage(self): if self.is_ipv4: usage = getattr(self, "_usage_cache", None) if usage is not None: # Use update_prefixes_usage results return usage size = IPv4(self.prefix).size if not size: return 100.0 n_ips = Address.objects.filter(prefix=self).count() n_pfx = sum( IPv4(p).size for p in Prefix.objects.filter(parent=self).only( "prefix").values_list("prefix", flat=True)) if n_ips: if size > 2: # Not /31 or /32 size -= 2 # Exclude broadcast and network return float(n_ips + n_pfx) * 100.0 / float(size) else: return None