コード例 #1
0
ファイル: ccp_util.py プロジェクト: nkaliape/ciscoconfparse
    def __init__(self, arg='::1/128', strict=False):

        #arg= _RGX_IPV6ADDR_NETMASK.sub(r'\1/\2', arg) # mangle IOS: 'addr mask'
        self.arg = arg
        self.dna = "IPv6Obj"

        try:
            mm = _RGX_IPV6ADDR.search(arg)
        except TypeError:
            if getattr(arg, 'dna', '') == "IPv6Obj":
                ip_str = '{0}/{1}'.format(str(arg.ip_object), arg.prefixlen)
                self.network_object = IPv6Network(ip_str, strict=False)
                self.ip_object = IPv6Address(str(arg.ip_object))
                return None
            elif isinstance(arg, IPv6Network):
                self.network_object = arg
                self.ip_object = IPv6Address(str(arg).split('/')[0])
                return None
            elif isinstance(arg, IPv6Address):
                self.network_object = IPv6Network(str(arg) + '/128')
                self.ip_object = IPv6Address(str(arg).split('/')[0])
                return None
            else:
                raise ValueError(
                    "IPv6Obj doesn't understand how to parse {0}".format(arg))

        assert (not (mm is None)), "IPv6Obj couldn't parse {0}".format(arg)
        self.network_object = IPv6Network(arg, strict=strict)
        self.ip_object = IPv6Address(mm.group(1))
コード例 #2
0
		def test_ipv6_order_multi(self):
			"""Test multiple IPv6 ordering."""
			t = Interfaces(ucr={
				'interfaces/eth0/ipv6/foo/address': '1:2:3:4:5:6:7:8',
				'interfaces/eth0/ipv6/foo/prefix': '64',
				'interfaces/eth1/order': '2',
				'interfaces/eth1/ipv6/default/address': '1:2:3:4:5:6:7:8',
				'interfaces/eth1/ipv6/default/prefix': '64',
				'interfaces/eth1/ipv6/a/address': '2:3:4:5:6:7:8:9',
				'interfaces/eth1/ipv6/a/prefix': '72',
				'interfaces/eth2/order': '1',
				'interfaces/eth2/ipv6/z/address': '1:2:3:4:5:6:7:8',
				'interfaces/eth2/ipv6/z/prefix': '64',
				'interfaces/eth2/ipv6/default/address': '2:3:4:5:6:7:8:9',
				'interfaces/eth2/ipv6/default/prefix': '72',
				'interfaces/primary': 'eth2,eth1',
				})
			self.assertEqual([],
					[s.name for _n, s in t.ipv4_interfaces])
			self.assertEqual([
				('eth2', 'default'),
				('eth2', 'z'),
				('eth1', 'default'),
				('eth1', 'a'),
				('eth0', 'foo')],
				[(s.name, n) for s, n in t.ipv6_interfaces])
			self.assertEqual(IPv6Network('2:3:4:5:6:7:8:9/72'),
					t.get_default_ip_address())
			self.assertEqual(None,
					t.get_default_ipv4_address())
			self.assertEqual(IPv6Network('2:3:4:5:6:7:8:9/72'),
					t.get_default_ipv6_address())
コード例 #3
0
ファイル: device.py プロジェクト: sthagen/adm6
 def _bsd_routingtab_line(self, line):
     """evaluate one line of OpenBSD routing-table,
     enter only, if useful content"""
     zeile = line.split()
     #print "# rt-read: "+ str(zeile)
     if len(zeile) > 0:
         targ = zeile.pop(0)
         if not ":" in targ:
             #nice_print("# !!! IPv4 Exception reading routingtable",targ)
             return
         try:
             target = IPv6Network(targ)
         except:
             """no IPv6 Address in column one"""
             #nice_print("# !!! Exception reading routingtable",targ)
             return
         try:
             hop = zeile.pop(0)
             nhp = IPv6Network(hop.strip())
             nhp._prefixlen = 128
             dev = zeile.pop(-1)
             self.routingtab.append([target, nhp, dev])
             #print "APPEND:",str([target, nhp, dev])
             return
         except:
             #print " something wrong reading bsd-routingtable"
             return
コード例 #4
0
 def __read_file(self, filename):
     """reads file using filename and creates self.entries
     for every line read successfully
     """
     try:
         file1 = open(filename, 'r')
     except:
         msg = "No readable file: %s" % filename
         raise ValueError, msg
     linenr = 0
     for zeile in file1:
         linenr = linenr + 1
         line = str(zeile)
         lefthalf = line.split('#')
         self.entries.sort(cmp=self.__mycmp__, key=None, reverse=False)
         try:
             (name, address) = lefthalf.pop(0).split()
             try:
                 ipad = IPv6Network(address)
                 if self.entries.count([name, ipad]) == 0:
                     self.entries.append([name, ipad])
             except:
                 print "User-Error: file:", filename
                 print "User-Error: line:", linenr
                 print "User-Error: content:", zeile
                 pass
             finally:
                 pass
         except:
             pass
     self.entries.sort(cmp=self.__mycmp__, key=None, reverse=False)
コード例 #5
0
 def network_object(self):
     try:
         if self.address_family == 'ip':
             return IPv4Network('%s/%s' % (self.network, self.netmask))
         elif self.address_family == 'ipv6':
             return IPv6Network('%s/%s' % (self.network, self.netmask))
     except:
         return None
コード例 #6
0
ファイル: ccp_util.py プロジェクト: micyew/ciscoconfparse
 def network(self):
     """Returns an IPv6Network object, which represents this network.
     """
     if sys.version_info[0] < 3:
         return self.network_object.network
     else:
         ## The ipaddress module returns an "IPAddress" object in Python3...
         return IPv6Network('{0}'.format(self.network_object.compressed))
コード例 #7
0
 def test_ipv6_multi(self):
     """Test multiple IPv6 interfaces."""
     t = Interfaces(
         ucr={
             'interfaces/eth0/ipv6/default/address': '1:2:3:4:5:6:7:8',
             'interfaces/eth0/ipv6/default/prefix': '64',
             'interfaces/eth1/ipv6/default/address': '2:3:4:5:6:7:8:9',
             'interfaces/eth1/ipv6/default/prefix': '64',
         })
     self.assertEqual([], [s.name for _n, s in t.ipv4_interfaces])
     self.assertEqual(['eth0', 'eth1'],
                      [s.name for s, _n in t.ipv6_interfaces])
     self.assertEqual(IPv6Network('1:2:3:4:5:6:7:8/64'),
                      t.get_default_ip_address())
     self.assertEqual(None, t.get_default_ipv4_address())
     self.assertEqual(IPv6Network('1:2:3:4:5:6:7:8/64'),
                      t.get_default_ipv6_address())
コード例 #8
0
ファイル: ccp_util.py プロジェクト: micyew/ciscoconfparse
    def __init__(self, arg='::1/128', strict=False):

        #arg= _RGX_IPV6ADDR_NETMASK.sub(r'\1/\2', arg) # mangle IOS: 'addr mask'
        self.arg = arg
        mm = _RGX_IPV6ADDR.search(arg)
        assert (not (mm is None)), "IPv6Obj couldn't parse {0}".format(arg)
        self.network_object = IPv6Network(arg, strict=strict)
        self.ip_object = IPv6Address(mm.group(1))
コード例 #9
0
		def test_ipv6(self):
			"""Test IPv6 functions."""
			i = _Iface({
				'name': 'NAME',
				'ipv6/default/address': '1:2:3:4:5:6:7:8',
				'ipv6/default/prefix': '64',
				'ipv6/other/address': '2:3:4:5:6:7:8:9',
				'ipv6/other/prefix': '80',
				})
			self.assertEqual('NAME', i.name)
			self.assertEqual(None, i.ipv4_address())
			self.assertEqual(IPv6Network('1:2:3:4:5:6:7:8/64'),
					i.ipv6_address())
			self.assertEqual(IPv6Network('1:2:3:4:5:6:7:8/64'),
					i.ipv6_address('default'))
			self.assertEqual(IPv6Network('2:3:4:5:6:7:8:9/80'),
					i.ipv6_address('other'))
コード例 #10
0
ファイル: device.py プロジェクト: sthagen/adm6
 def interface_line(self, line):
     """evaluate one line of ifconfig-output
     store results in self.interfaces = []
     !!! specific on os-type !!!
     """
     #    if 'Win-XP' in self.device_os:
     #        """german version only for now"""
     #        if line.startswith('Schnittstelle '):
     #            righthalf = line.rsplit(':')
     #            ifacename = righthalf.pop(-1).strip()
     #            self.int_name = ifacename
     #        else:
     #            items = line.split()
     #            if len(items) > 1:
     #                targ = items.pop(-1)
     #                try:
     #                    target = IPv6Network(targ)
     #                except AddressValueError, e:
     #                    """no IPv6 Address in last column """
     #                    return
     #                self.int_addr = target
     #                self.interfaces.append([self.int_name, self.int_addr])
     #        return
     nam = re.findall('^[a-z]+[ 0-9][ :] ', line, flags=0)
     if nam:
         self.int_name = nam.pop(0).strip()
     add = []
     if 'Linux' in self.device_os:
         add = re.findall('\s*inet6\ .* Scope:*', line, flags=0)
         if add:
             ine = add.pop(0).split()
             adr = ine.pop(2)
             self.int_addr = IPv6Network(adr)
             self.interfaces.append([self.int_name, self.int_addr])
     if 'OpenBSD' in self.device_os:
         if 'inet6' in line:
             if '%' in line:
                 (le, ri) = line.split('%')
             else:
                 le = line
             ine = le.split()
             adr = ine.pop(1)
             self.int_addr = IPv6Network(adr)
             self.interfaces.append([self.int_name, self.int_addr])
         return
コード例 #11
0
ファイル: common.py プロジェクト: bopopescu/corporate-server
def convert_udm_subnet_to_ipv6_network(subnet):
    prefix = subnet.replace(":", "")
    count = len(prefix)
    assert 1 <= count <= 32
    prefix_length = 4 * count
    address = subnet
    if count <= 28:
        address += "::"
    return IPv6Network("%s/%d" % (address, prefix_length))
コード例 #12
0
 def ip_network(self):
     if self.afi == 1:
         ip = IPv4Address(Bytes(self.value[:4]))
         ipnet = IPv4Network(
             str(ip) + '/' + str(bytes_to_int(self.value[4])))
     else:
         ip = IPv6Address(Bytes(self.value[:16]))
         ipnet = IPv6Network(
             str(ip) + '/' + str(bytes_to_int(self.value[16])))
     return IPNetwork(str(ipnet))
コード例 #13
0
ファイル: test_01_hostnet6.py プロジェクト: sthagen/adm6
 def test_06_get_address(self):
     """
     hn-06 get_addrs returns list of given hostname
     """
     file1 = "reference-hostnet"
     my_err = False
     try:
         hn6 = HostNet6(file1)
     except:
         my_err = True
     self.assertFalse(my_err)
     #print "T6:", hn6.entries
     #print "GA1", hn6.get_addrs("host-one")
     #print "GA2", hn6.get_addrs("host-two")
     self.assertEquals([IPv6Network('2010:db8:1:beed::23/128')],
                       hn6.get_addrs('host-one'))
     self.assertEquals( \
         ('host-one', [IPv6Network('2010:db8:1:beed::23/128')]), \
         hn6.show_addr('host-one'))
コード例 #14
0
ファイル: test_01_hostnet6.py プロジェクト: sthagen/adm6
 def test_03_evaluate_entries(self):
     """
     hn-03 evaluate entries of reference-hostnet
     """
     file = "reference-hostnet"
     content = [ \
         ['any', IPv6Network('2000::/3')], \
         ['beaf', IPv6Network('2001:db8:beaf::/48')], \
         ['host-one', IPv6Network('2010:db8:1:beed::23/128')], \
         ['localhost', IPv6Network('::1/128')], \
         ['many', IPv6Network('::/0')]]
     my_err = False
     try:
         hn6 = HostNet6(file)
         print hn6.entries
     except:
         my_err = True
     print content
     self.assertEquals(content, hn6.entries)
コード例 #15
0
def testIPv6Obj_attributes():
    ## Ensure that attributes are accessible and pass the smell test
    test_object = IPv6Obj("2001::dead:beef/64")
    results_correct = [
        ("ip", IPv6Address("2001::dead:beef")),
        ("ip_object", IPv6Address("2001::dead:beef")),
        ("netmask", IPv6Address("ffff:ffff:ffff:ffff::")),
        ("prefixlen", 64),
        ("network", IPv6Network("2001::/64")),
        ("network_object", IPv6Network("2001::/64")),
        ("hostmask", IPv6Address("::ffff:ffff:ffff:ffff")),
        ("numhosts", 18446744073709551616),
        ("version", 6),
        ("is_reserved", False),
        ("is_multicast", False),
        # ("is_private", False),  # FIXME: disabling this for now...
        # py2.7 and py3.x produce different results
        ("as_cidr_addr", "2001::dead:beef/64"),
        ("as_cidr_net", "2001::/64"),
        ("as_decimal", 42540488161975842760550356429036175087),
        ("as_decimal_network", 42540488161975842760550356425300246528),
        (
            "as_hex_tuple",
            ("2001", "0000", "0000", "0000", "0000", "0000", "dead", "beef"),
        ),
        (
            "as_binary_tuple",
            (
                "0010000000000001",
                "0000000000000000",
                "0000000000000000",
                "0000000000000000",
                "0000000000000000",
                "0000000000000000",
                "1101111010101101",
                "1011111011101111",
            ),
        ),
    ]
    for attribute, result_correct in results_correct:

        assert getattr(test_object, attribute) == result_correct
コード例 #16
0
ファイル: device.py プロジェクト: sthagen/adm6
 def address_is_own(self, value):
     """
     check, if given address is interface-address of ThisDevice
     returns Name of Interface or None
     """
     for interface in self.interfaces:
         [iface_name, target_IP] = interface
         target = IPv6Network(target_IP)
         if target.ip == value.ip:
             return True
     return False
コード例 #17
0
 def test_ipv6_order(self):
     """Test IPv6 ordering."""
     t = Interfaces(
         ucr={
             'interfaces/eth0/ipv6/default/address': '1:2:3:4:5:6:7:8',
             'interfaces/eth0/ipv6/default/prefix': '64',
             'interfaces/eth1/ipv6/default/address': '2:3:4:5:6:7:8:9',
             'interfaces/eth1/ipv6/default/prefix': '72',
             'interfaces/eth2/order': '1',
             'interfaces/eth2/ipv6/default/address': '3:4:5:6:7:8:9:a',
             'interfaces/eth2/ipv6/default/prefix': '80',
         })
     self.assertEqual([], [s.name for _n, s in t.ipv4_interfaces])
     self.assertEqual(['eth2', 'eth0', 'eth1'],
                      [s.name for s, _n in t.ipv6_interfaces])
     self.assertEqual(IPv6Network('1:2:3:4:5:6:7:8/64'),
                      t.get_default_ip_address())
     self.assertEqual(None, t.get_default_ipv4_address())
     self.assertEqual(IPv6Network('1:2:3:4:5:6:7:8/64'),
                      t.get_default_ipv6_address())
コード例 #18
0
ファイル: device.py プロジェクト: sthagen/adm6
 def _debian_routingtab_line(self, line):
     """
     evaluate one line of debian ipv6 routingtable
     and append it to routingtab, which is a list of routing entries
     """
     words = line.split()
     w1 = words.pop(0).strip()
     if not line.find("unreachable"):
         return
     if not line.find("default") and line.find("via") > 0:
         target = '::/0'
         via = words.pop(1)
         interf = words.pop(2)
     else:
         target = w1
         if line.find("via") == -1:
             interf = words.pop(1)
             via = "::/0"
         else:
             via = words.pop(1)
             interf = words.pop(2)
     self.routingtab.append([IPv6Network(target), IPv6Network(via), interf])
コード例 #19
0
ファイル: test_01_hostnet6.py プロジェクト: sthagen/adm6
 def test_04_evaluate_appended_entries_fail(self):
     """
     hn-04 entries of reference-hostnet-fail are not appended
     """
     file1 = "reference-hostnet"
     file2 = "reference-hostnet-fail"
     content = [ \
         ['any', IPv6Network('2000::/3')], \
         ['beaf', IPv6Network('2001:db8:beaf::/48')], \
         ['host-one', IPv6Network('2010:db8:1:beed::23/128')], \
         ['localhost', IPv6Network('::1/128')], \
         ['many', IPv6Network('::/0')]]
     my_err = False
     try:
         hn6 = HostNet6(file1)
     except:
         my_err = True
     try:
         hn6.append(file2)
     except:
         my_err = True
     self.assertTrue(my_err)
     #print "HN:", hn6.entries
     self.assertEquals(content, hn6.entries)
コード例 #20
0
 def to_dict(self):
     d = {}
     for name, _ in self.__class__.fields:
         d[name] = getattr(self, name)
         if name in ('to', ):
             d[name] = '0x' + encode_hex(d[name])
         elif name in ('value', ):
             if self.afi == 1:
                 ip = IPv4Address(Bytes(d[name][:4]))
                 net = IPv4Network(
                     str(ip) + '/' + str(bytes_to_int(d[name][4])))
                 d[name] = str(net)
             else:
                 ip = IPv6Address(Bytes(d[name][:16]))
                 net = IPv6Network(
                     str(ip) + '/' + str(bytes_to_int(d[name][16])))
                 d[name] = str(net)
         elif name in ('metadata', ) and self.category == 2:
             _metadata = []
             i = 0
             while i < len(d[name]):
                 _metadata.append(bytes_to_int(d[name][i]))
                 if _metadata[-1] == 1:
                     ip = IPv4Address(Bytes(d[name][i + 1]))
                 else:
                     ip = IPv6Address(Bytes(d[name][i + 1]))
                 _metadata.append(str(ip))
                 _metadata.append(encode_hex(d[name][i + 2]))
                 i += 3
             d[name] = _metadata
         elif name in ('metadata', ) and self.category == 3:
             _metadata = []
             i = 0
             while i < len(d[name]):
                 _metadata.append(bytes_to_int(d[name][i]))
                 if _metadata[-1] == 1:
                     ip = IPv4Address(Bytes(d[name][i + 1]))
                 else:
                     ip = IPv6Address(Bytes(d[name][i + 1]))
                 _metadata.append(str(ip))
                 _metadata.append(bytes_to_int(d[name][i + 2]))
                 _metadata.append(bytes_to_int(d[name][i + 3]))
                 i += 4
             d[name] = _metadata
     d['sender'] = '0x' + encode_hex(self.sender)
     d['hash'] = '0x' + encode_hex(self.hash)
     return d
コード例 #21
0
 def test_ipv6_disjunct(self):
     """Test disjunct IPv4 IPv6 interfaces."""
     t = Interfaces(
         ucr={
             'interfaces/eth0/address': '2.3.4.5',
             'interfaces/eth0/netmask': '255.255.255.0',
             'interfaces/eth1/ipv6/default/address': '1:2:3:4:5:6:7:8',
             'interfaces/eth1/ipv6/default/prefix': '64',
         })
     self.assertEqual(['eth0'], [s.name for _n, s in t.ipv4_interfaces])
     self.assertEqual(['eth1'], [s.name for s, _n in t.ipv6_interfaces])
     self.assertEqual(IPv4Network('2.3.4.5/24'),
                      t.get_default_ip_address())
     self.assertEqual(IPv4Network('2.3.4.5/24'),
                      t.get_default_ipv4_address())
     self.assertEqual(IPv6Network('1:2:3:4:5:6:7:8/64'),
                      t.get_default_ipv6_address())
コード例 #22
0
ファイル: device.py プロジェクト: sthagen/adm6
 def look_for(self, addr):
     """
     seeks addr in routing-table, returns tuple of
     interface-name and line number of routing-entry
     """
     interface = u'undef'
     route_number = -1
     ad = IPv6Network(addr)
     #print "LOOK_for: " + str(ad),
     for route in self.routingtab:
         route_number += 1
         (rte, nhp, dev) = route
         result = rte.__contains__(ad)
         if result:
             interface = dev
             #print "RETURN1: " + str(interface) + " Line: "+ str(route_number)
             return (interface, route_number)
     #print "RETURN2: " + str(interface) + " Line: "+ str(route_number)
     return (interface, route_number)
コード例 #23
0
ファイル: test_01_hostnet6.py プロジェクト: sthagen/adm6
 def test_05_evaluate_appended_entries_ok(self):
     """
     hn-05 entries of reference-hostnet-append are appended
     """
     file1 = "reference-hostnet"
     file2 = "reference-hostnet-append"
     content = [ \
         ['any', IPv6Network('2000::/3')], \
         ['beaf', IPv6Network('2001:db8:beaf::/48')], \
         ['host-one', IPv6Network('2010:db8:1:beed::23/128')], \
         ['host-one', IPv6Network('2010:db8:1:beed::6/128')], \
         ['host-two', IPv6Network('2010:db8:1:beed::7/128')], \
         ['localhost', IPv6Network('::1/128')], \
         ['many', IPv6Network('::/0')]]
     my_err = False
     try:
         hn6 = HostNet6(file1)
         hn6.append(file2)
     except:
         my_err = True
     self.assertEquals(content, hn6.entries)
コード例 #24
0
        asns = asns.split()
        assert asns

    except Exception:
        if DEBUG: print_exc()
        sys.exit(1)

    asns = [asn.replace('AS', '') for asn in asns]

    nets = list()
    collapsed = None
    for asn in asns:
        try:
            result = db.get_as_prefixes(asn)
            if result:
                for net in result:
                    if IPNetwork(net).version == 4 and IPNetwork(
                            net).version == af:
                        nets.append(IPv4Network(net))
                    if IPNetwork(net).version == 6 and IPNetwork(
                            net).version == af:
                        nets.append(IPv6Network(net))

            collapsed = [str(net) for net in collapse_address_list(nets)]

        except Exception:
            if DEBUG: print_exc()
            pass

    if collapsed: print '\n'.join(collapsed)
コード例 #25
0
 class user_ipv6:
     address = IPv6Network("2001:db8:0::/48")
     gateway = IPv6Address("2001:db8:0::1")
     reserved_addresses_bottom = 10
     reserved_addresses_top = 2
     vlan = VLANData.vlan_dummy1
コード例 #26
0
	def ipv6_address(self, name='default'):
		"""Return IPv6 address."""
		key = '%%(ipv6/%s/address)s/%%(ipv6/%s/prefix)s' % (name, name)
		return IPv6Network(key % self)
コード例 #27
0
ファイル: ccp_util.py プロジェクト: 0x434F6869/ciscoconfparse
 def prefixlen(self, arg):
     """prefixlen setter method"""
     self.network_object = IPv6Network("{0}/{1}".format(
         str(self.ip_object), arg),
                                       strict=False)
コード例 #28
0
    def __init__(self,
                 nonce,
                 category,
                 to,
                 afi,
                 value,
                 metadata=b'',
                 time=0,
                 v=0,
                 r=0,
                 s=0):

        if category == 0 or category == 1:
            if metadata != b'':
                raise InvalidTransaction("Invalid Metadata")
            metadata = b''
        elif category == 2:
            if type(metadata) == list and len(metadata) % 3 == 0:
                _metadata = []
                _afi = 0
                if type(metadata[0]) == bytes:
                    _bytes = True
                elif type(metadata[0]) == int:
                    _bytes = False
                else:
                    raise InvalidTransaction("Invalid Metadata")
                i = 0
                while i < len(metadata):
                    try:
                        if _bytes:
                            _afi = bytes_to_int(metadata[i])
                            _metadata.append(metadata[i])
                        else:
                            _afi = metadata[i]
                            _metadata.append(encode_int8(metadata[i]))
                        if _afi != 1 and _afi != 2:
                            raise InvalidTransaction("Invalid Metadata AFI")
                    except:
                        raise InvalidTransaction("Invalid Metadata AFI")
                    try:
                        if _bytes:
                            if _afi == 1:
                                ip = IPv4Address(Bytes(metadata[i + 1]))
                            else:
                                ip = IPv6Address(Bytes(metadata[i + 1]))
                            _metadata.append(bytes(ip.packed))
                            addr = normalize_address(metadata[i + 2],
                                                     allow_blank=True)
                            _metadata.append(addr)
                        else:
                            if _afi == 1:
                                ip = IPv4Address(metadata[i + 1])
                            else:
                                ip = IPv6Address(metadata[i + 1])
                            _metadata.append(bytes(ip.packed))
                            addr = normalize_address(metadata[i + 2],
                                                     allow_blank=True)
                            _metadata.append(addr)
                        i += 3
                    except:
                        raise InvalidTransaction("Invalid Metadata")
                metadata = _metadata
            else:
                raise InvalidTransaction("Invalid Metadata")

        elif category == 3:
            if type(metadata) == list and len(metadata) % 4 == 0:
                _metadata = []
                _afi = 0
                if type(metadata[0]) == bytes:
                    _bytes = True
                elif type(metadata[0]) == int:
                    _bytes = False
                else:
                    raise InvalidTransaction("Invalid Metadata")
                i = 0
                while i < len(metadata):
                    try:
                        if _bytes:
                            _afi = bytes_to_int(metadata[i])
                            _metadata.append(metadata[i])
                        else:
                            _afi = metadata[i]
                            _metadata.append(encode_int8(metadata[i]))
                        if _afi != 1 and _afi != 2:
                            raise InvalidTransaction("Invalid Metadata AFI")
                    except:
                        raise InvalidTransaction("Invalid Metadata AFI")
                    try:
                        if _bytes:
                            if _afi == 1:
                                ip = IPv4Address(Bytes(metadata[i + 1]))
                            else:
                                ip = IPv6Address(Bytes(metadata[i + 1]))
                            _metadata.append(bytes(ip.packed))
                            priority = bytes_to_int(metadata[i + 2])
                            if priority < 0 or priority > 255:
                                raise InvalidTransaction(
                                    "Invalid Metadata Priority")
                            _metadata.append(int_to_bytes(priority))
                            weight = bytes_to_int(metadata[i + 3])
                            if weight < 0 or weight > 255:
                                raise InvalidTransaction(
                                    "Invalid Metadata Weight")
                            _metadata.append(int_to_bytes(weight))
                        else:
                            if _afi == 1:
                                ip = IPv4Address(metadata[i + 1])
                            else:
                                ip = IPv6Address(metadata[i + 1])
                            _metadata.append(bytes(ip.packed))
                            priority = metadata[i + 2]
                            if priority < 0 or priority > 255:
                                raise InvalidTransaction(
                                    "Invalid Metadata Priority")
                            _metadata.append(int_to_bytes(priority))
                            weight = metadata[i + 3]
                            if weight < 0 or weight > 255:
                                raise InvalidTransaction(
                                    "Invalid Metadata Weight")
                            _metadata.append(int_to_bytes(weight))
                        i += 4
                    except:
                        raise InvalidTransaction("Invalid Metadata")
                metadata = _metadata
            else:
                raise InvalidTransaction("Invalid Metadata")
        else:
            raise InvalidTransaction("Invalid Category")

        to = normalize_address(to, allow_blank=True)

        if afi != 1 and afi != 2:
            raise InvalidTransaction("Invalid AFI")

        try:
            if afi == 1:
                ipnet = IPv4Network(value)
            else:
                ipnet = IPv6Network(value)
        except:
            if len(value) == 5:
                try:
                    ip = IPv4Address(Bytes(value[:4]))
                    ipnet = IPv4Network(
                        str(ip) + '/' + str(bytes_to_int(value[4])))
                except:
                    raise InvalidTransaction("Invalid Value")
            elif len(value) == 17:
                try:
                    ip = IPv6Address(Bytes(value[:16]))
                    ipnet = IPv6Network(
                        str(ip) + '/' + str(bytes_to_int(value[16])))
                except:
                    raise InvalidTransaction("Invalid Value")
            else:
                raise InvalidTransaction("Invalid Value")
        value = bytes(ipnet.packed) + encode_int8(ipnet.prefixlen)

        super(Transaction, self).__init__(nonce, category, to, afi, value,
                                          metadata, time, v, r, s)