示例#1
0
	def unpack (cls, exdata):
		data = exdata

		# Get the data length to understand if addresses are IPv4 or IPv6
		datalen = len(data)

		rd = RouteDistinguisher.unpack(data[:8])
		data = data[8:]

		esi = ESI.unpack(data[:10])
		data = data[10:]

		etag = EthernetTag.unpack(data[:4])
		data = data[4:]

		iplen = ord(data[0])
		data = data[1:]

		if datalen == (26 + 8):  # Using IPv4 addresses
			ip = IP.unpack(data[:4])
			data = data[4:]
			gwip = IP.unpack(data[:4])
			data = data[4:]
		elif datalen == (26 + 32):  # Using IPv6 addresses
			ip = IP.unpack(data[:16])
			data = data[16:]
			gwip = IP.unpack(data[:16])
			data = data[16:]
		else:
			raise Notify(3,5,"Data field length is given as %d, but EVPN route currently support only IPv4 or IPv6(34 or 58)" % iplen)

		label = Labels.unpack(data[:3])

		return cls(rd,esi,etag,label,ip,iplen,gwip,exdata)
示例#2
0
文件: route.py 项目: Shmuma/exabgp
	def next_hop (self, scope, name, command, tokens):
		if scope[-1]['announce'][-1].attributes.has(Attribute.CODE.NEXT_HOP):
			return self.error.set(self.syntax)

		try:
			# next-hop self is unsupported
			ip = tokens.pop(0)
			if ip.lower() == 'self':
				if 'local-address' in scope[-1]:
					la = scope[-1]['local-address']
				elif self._nexthopself:
					la = self._nexthopself
				else:
					return self.error.set('next-hop self can only be specified with a neighbor')
				nh = IP.unpack(la.pack())
			else:
				nh = IP.create(ip)

			change = scope[-1]['announce'][-1]
			nlri = change.nlri
			afi = nlri.afi
			safi = nlri.safi

			nlri.nexthop = nh

			if afi == AFI.ipv4 and safi in (SAFI.unicast,SAFI.multicast):
				change.attributes.add(Attribute.unpack(NextHop.ID,NextHop.FLAG,nh.packed,None))
				# NextHop(nh.ip,nh.packed) does not cache the result, using unpack does
				# change.attributes.add(NextHop(nh.ip,nh.packed))

			return True
		except Exception:
			return self.error.set(self.syntax)
示例#3
0
    def test99_EVPNMACCreatePackUnpack(self):
        '''Test pack/unpack for E-VPN MAC routes'''
        nlri = EVPNMAC(RouteDistinguisher.fromElements("42.42.42.42", 5),
                       ESI(),
                       EthernetTag(111),
                       MAC("01:02:03:04:05:06"), 6*8,
                       Labels([42], True),
                       IP.create("1.1.1.1"))

        packed = nlri.pack()

        unpacked,leftover = EVPN.unpack_nlri(AFI(AFI.l2vpn), SAFI(SAFI.evpn),
                                             packed, OUT.UNSET, None)

        self.assertEqual(0, len(leftover))

        # TODO: compare packed with a reference encoding verified 
        # as conformant with RFC7432

        self.assertTrue(isinstance(unpacked, EVPNMAC))

        self.assertEqual("42.42.42.42:5", unpacked.rd._str())
        self.assertEqual(ESI.DEFAULT, unpacked.esi.esi)
        self.assertEqual(EthernetTag(111), unpacked.etag)
        self.assertEqual(MAC("01:02:03:04:05:06"), unpacked.mac)

        self.assertEqual(IP.create("1.1.1.1"), unpacked.ip)

        self.assertEqual(1, len(unpacked.label.labels))
        self.assertEqual(42, unpacked.label.labels[0])
示例#4
0
 def listen_on(self, local_addr, remote_addr, port, md5_password,
               md5_base64, ttl_in):
     try:
         if not remote_addr:
             remote_addr = IP.create(
                 '0.0.0.0') if local_addr.ipv4() else IP.create('::')
         self._listen(local_addr, remote_addr, port, md5_password,
                      md5_base64, ttl_in)
         self.logger.debug(
             'listening for BGP session(s) on %s:%d%s' %
             (local_addr, port, ' with MD5' if md5_password else ''),
             'network')
         return True
     except NetworkError as exc:
         if os.geteuid() != 0 and port <= 1024:
             self.logger.critical(
                 'can not bind to %s:%d, you may need to run ExaBGP as root'
                 % (local_addr, port), 'network')
         else:
             self.logger.critical(
                 'can not bind to %s:%d (%s)' %
                 (local_addr, port, str(exc)), 'network')
         self.logger.critical(
             'unset exabgp.tcp.bind if you do not want listen for incoming connections',
             'network')
         self.logger.critical(
             'and check that no other daemon is already binding to port %d'
             % port, 'network')
         return False
示例#5
0
文件: route.py 项目: Shmuma/exabgp
	def insert_static_route (self, scope, name, command, tokens):
		try:
			ip = tokens.pop(0)
		except IndexError:
			return self.error.set(self.syntax)
		try:
			ip,mask = ip.split('/')
			mask = int(mask)
		except ValueError:
			mask = 32
		try:
			if 'rd' in tokens:
				klass = MPLS
			elif 'route-distinguisher' in tokens:
				klass = MPLS
			elif 'label' in tokens:
				klass = MPLS
			else:
				klass = INET

			# nexthop must be false and its str return nothing .. an empty string does that
			update = Change(klass(afi=IP.toafi(ip),safi=IP.tosafi(ip),packed=IP.pton(ip),mask=mask,nexthop=None,action=OUT.ANNOUNCE),Attributes())
		except ValueError:
			return self.error.set(self.syntax)

		if 'announce' not in scope[-1]:
			scope[-1]['announce'] = []

		scope[-1]['announce'].append(update)
		return True
示例#6
0
 def parse_api_attribute(self, command, peers, action):
     # This is a quick solution which does not support next-hop self
     attribute, nlris = command.split('nlri')
     route = '%s route 0.0.0.0/0 %s' % (action, ' '.join(
         attribute.split()[2:]))
     parsed = self.parse_api_route(route, peers, action)
     if parsed in (True, False, None):
         return parsed
     attributes = parsed[0][1].attributes
     nexthop = parsed[0][1].nlri.nexthop
     changes = []
     for nlri in nlris.split():
         ip, mask = nlri.split('/')
         klass = Prefix if 'path-information' in command else MPLS
         change = Change(
             klass(afi=IP.toafi(ip),
                   safi=IP.tosafi(ip),
                   packed=IP.pton(ip),
                   mask=int(mask),
                   nexthop=nexthop.packed,
                   action=action), attributes)
         if action == 'withdraw':
             change.nlri.action = OUT.withdraw
         else:
             change.nlri.action = OUT.announce
         changes.append((peers.keys(), change))
     return changes
示例#7
0
def redirect (tokeniser):
	data = tokeniser()
	count = data.count(':')
	if count == 0:
		return IP.create(data), ExtendedCommunities().add(TrafficNextHopSimpson(False))
	if count == 1:
		prefix,suffix = data.split(':',1)
		if prefix.count('.'):
			raise ValueError('this format has been deprecated as it does not make sense and it is not supported by other vendors')

		asn = int(prefix)
		route_target = int(suffix)

		if asn >= pow(2, 32):
			raise ValueError('asn is a 32 bits number, value too large %s' % asn)
		if asn >= pow(2,16):
			if route_target >= pow(2, 16):
				raise ValueError('asn is a 32 bits number, route target can only be 16 bit %s' % route_target)
			return NoNextHop, ExtendedCommunities().add(TrafficRedirectASN4(asn, route_target))
		if route_target >= pow(2,32):
			raise ValueError('route target is a 32 bits number, value too large %s' % route_target)
		return NoNextHop,ExtendedCommunities().add(TrafficRedirect(asn,route_target))
	else:
		elements = data.split(':')
		ip = ':'.join(elements[:-1])
		asn = int(elements[-1])
		return IP.create(ip), ExtendedCommunities().add(TrafficRedirectIPv6(ip,asn))
示例#8
0
	def api_attribute (self, command, peers, action):
		# This is a quick solution which does not support next-hop self
		attribute,nlris = command.split('nlri')
		route = '%s route 0.0.0.0/0 %s' % (action, ' '.join(attribute.split()[2:]))
		parsed = self.api_route(peers,route)
		if parsed in (True,False,None):
			return parsed
		attributes = parsed[0][1].attributes
		nexthop = parsed[0][1].nlri.nexthop
		changes = []
		for nlri in nlris.split():
			ip,mask = nlri.split('/')
			klass = MPLS if 'path-information' in command else INET
			change = Change(
				klass(
					afi=IP.toafi(ip),
					safi=IP.tosafi(ip),
					packed=IP.pton(ip),
					mask=int(mask),
					nexthop='',  # could be NextHopSelf
					action=action
				),
				attributes
			)
			change.nlri.nexthop = nexthop
			if action == 'withdraw':
				change.nlri.action = OUT.WITHDRAW
			else:
				change.nlri.action = OUT.ANNOUNCE
			changes.append((peers.keys(),change))
		return changes
示例#9
0
    def test100_EVPNMACHashEqual(self):
        '''
        Two indistinct EVPN NLRI should
        hash to the same value, and be equal
        '''

        nlri1 = EVPNMAC(
            RouteDistinguisher.fromElements("42.42.42.42", 5),
            ESI(),
            EthernetTag(111),
            MAC("01:02:03:04:05:06"),
            6 * 8,
            Labels([42], True),
            IP.create("1.1.1.1"),
        )

        nlri2 = EVPNMAC(
            RouteDistinguisher.fromElements("42.42.42.42", 5),
            ESI(),
            EthernetTag(111),
            MAC("01:02:03:04:05:06"),
            6 * 8,
            Labels([42], True),
            IP.create("1.1.1.1"),
        )

        self.assertEqual(hash(nlri1), hash(nlri2))
        self.assertEqual(nlri1, nlri2)
示例#10
0
    def test99_EVPNMACCreatePackUnpack(self):
        '''Test pack/unpack for E-VPN MAC routes'''
        nlri = EVPNMAC(
            RouteDistinguisher.fromElements("42.42.42.42", 5),
            ESI(),
            EthernetTag(111),
            MAC("01:02:03:04:05:06"),
            6 * 8,
            Labels([42], True),
            IP.create("1.1.1.1"),
        )

        packed = nlri.pack()

        unpacked, leftover = EVPN.unpack_nlri(AFI.l2vpn, SAFI.evpn, packed,
                                              OUT.UNSET, None)

        self.assertEqual(0, len(leftover))

        # TODO: compare packed with a reference encoding verified
        # as conformant with RFC7432

        self.assertTrue(isinstance(unpacked, EVPNMAC))

        self.assertEqual("42.42.42.42:5", unpacked.rd._str())
        self.assertEqual(ESI.DEFAULT, unpacked.esi.esi)
        self.assertEqual(EthernetTag(111), unpacked.etag)
        self.assertEqual(MAC("01:02:03:04:05:06"), unpacked.mac)

        self.assertEqual(IP.create("1.1.1.1"), unpacked.ip)

        self.assertEqual(1, len(unpacked.label.labels))
        self.assertEqual(42, unpacked.label.labels[0])
示例#11
0
	def parse_api_attribute (self,command,peers,action):
		# This is a quick solution which does not support next-hop self
		attribute,nlris = command.split('nlri')
		route = '%s route 0.0.0.0/0 %s' % (action, ' '.join(attribute.split()[2:]))
		parsed = self.parse_api_route(route,peers,action)
		if parsed in (True,False,None):
			return parsed
		attributes = parsed[0][1].attributes
		nexthop = parsed[0][1].nlri.nexthop
		changes = []
		for nlri in nlris.split():
			ip,mask = nlri.split('/')
			klass = Prefix if 'path-information' in command else MPLS
			change = Change(
				klass(
					afi=IP.toafi(ip),
					safi=IP.tosafi(ip),
					packed=IP.pton(ip),
					mask=int(mask),
					nexthop=nexthop.packed,
					action=action
				)
				,attributes
			)
			if action == 'withdraw':
				change.nlri.action = OUT.withdraw
			else:
				change.nlri.action = OUT.announce
			changes.append((peers.keys(),change))
		return changes
示例#12
0
    def test99_EVPNPrefixCreatePackUnpack(self):
        '''Test pack/unpack for E-VPN Prefix routes'''

        nlri = EVPNPrefix(RouteDistinguisher.fromElements("42.42.42.42", 5),
                          ESI(),
                          EthernetTag(111),
                          Labels([42], True),
                          IP.create("1.1.1.0"),24,
                          IP.create("2.2.2.2"),
                          )

        packed = nlri.pack()

        unpacked,leftover = EVPN.unpack_nlri(AFI.l2vpn, SAFI.evpn,
                                             packed, OUT.UNSET, None)

        self.assertEqual(0, len(leftover))

        # TODO: compare packed with a reference encoding verified
        # as conformant with RFC7432

        self.assertTrue(isinstance(unpacked, EVPNPrefix))

        self.assertEqual("42.42.42.42:5", unpacked.rd._str())
        self.assertEqual(ESI.DEFAULT, unpacked.esi.esi)
        self.assertEqual(EthernetTag(111), unpacked.etag)
        self.assertEqual(IP.create("1.1.1.0"), unpacked.ip)
        self.assertEqual(24, unpacked.iplen)
        self.assertEqual(IP.create("2.2.2.2"), unpacked.gwip)
        self.assertEqual(1, len(unpacked.label.labels))
        self.assertEqual(42, unpacked.label.labels[0])
示例#13
0
    def test3_IPVPNHashEqual(self):
        '''
        Two VPN NLRI distinct only by their *action* should
        hash to the same value, and be equal
        '''

        packedPrefix, mask = prefixToPackedIPMask("1.1.1.1/32")

        nlri1 = IPVPN.new(AFI(AFI.ipv4), SAFI(SAFI.mpls_vpn),
                          packedPrefix, mask,
                          Labels([42], True),
                          RouteDistinguisher.fromElements("42.42.42.42", 5),
                          IP.pton("45.45.45.45"),
                          OUT.ANNOUNCE)

        nlri2 = IPVPN.new(AFI(AFI.ipv4), SAFI(SAFI.mpls_vpn),
                          packedPrefix, mask,
                          Labels([42], True),
                          RouteDistinguisher.fromElements("42.42.42.42", 5),
                          IP.pton("45.45.45.45"),
                          OUT.WITHDRAW)

        self.assertEqual(hash(nlri1), hash(nlri2))
        self.assertTrue(nlri1.eq(nlri2))
        self.assertEqual(nlri1, nlri2)
示例#14
0
	def unpack (cls, exdata):
		data = exdata

		# Get the data length to understand if addresses are IPv4 or IPv6
		datalen = len(data)

		rd = RouteDistinguisher.unpack(data[:8])
		data = data[8:]

		esi = ESI.unpack(data[:10])
		data = data[10:]

		etag = EthernetTag.unpack(data[:4])
		data = data[4:]

		iplen = ord(data[0])
		data = data[1:]

		if datalen == (26 + 8):  # Using IPv4 addresses
			ip = IP.unpack(data[:4])
			data = data[4:]
			gwip = IP.unpack(data[:4])
			data = data[4:]
		elif datalen == (26 + 32):  # Using IPv6 addresses
			ip = IP.unpack(data[:16])
			data = data[16:]
			gwip = IP.unpack(data[:16])
			data = data[16:]
		else:
			raise Notify(3,5,"Data field length is given as %d, but EVPN route currently support only IPv4 or IPv6(34 or 58)" % iplen)

		label = Labels.unpack(data[:3])

		return cls(rd,esi,etag,label,ip,iplen,gwip,exdata)
示例#15
0
	def unpack (cls,data,length):
		if len(data) == 4:
			# IPv4 address
			terid = IP.unpack(data[:4])
		elif len(data) == 16:
			# IPv6
			terid = IP.unpack(data[:16])
		return cls(terid=terid)
示例#16
0
def inet(tokeniser):
    ipmask = prefix(tokeniser)
    inet = INET(afi=IP.toafi(ipmask.top()),
                safi=IP.tosafi(ipmask.top()),
                action=OUT.UNSET)
    inet.cidr = CIDR(ipmask.ton(), ipmask.mask)

    return Change(inet, Attributes())
示例#17
0
	def unpack (cls, data):
		if len(data) == 4:
			# IPv4 address
			addr = IP.unpack(data[:4])
		elif len(data) == 16:
			# IPv6
			addr = IP.unpack(data[:16])
		return cls(iface_addr=addr)
示例#18
0
 def unpack(cls, data):
     if len(data) == 4:
         # IPv4 address
         addr = IP.unpack(data[:4])
     elif len(data) == 16:
         # IPv6
         addr = IP.unpack(data[:16])
     return cls(iface_addr=addr)
示例#19
0
 def unpack(cls, data, length):
     if len(data) == 4:
         # IPv4 address
         terid = IP.unpack(data[:4])
     elif len(data) == 16:
         # IPv6
         terid = IP.unpack(data[:16])
     return cls(terid=terid)
示例#20
0
def mpls(tokeniser):
    ipmask = prefix(tokeniser)
    mpls = IPVPN(afi=IP.toafi(ipmask.top()),
                 safi=IP.tosafi(ipmask.top()),
                 action=OUT.ANNOUNCE)
    mpls.cidr = CIDR(ipmask.ton(), ipmask.mask)

    return Change(mpls, Attributes())
示例#21
0
        def unpack (cls, afi, safi, data, addpath, nexthop, action):
                local_node_id = ""
                local_asn = ""
                local_ipv4 = ""
                remote_node_id = ""
                remote_asn = ""
                remote_ipv4 = ""
                
                nlri_type = data[0:2]
                nlri_length, = unpack('!H',data[2:4])
                protocol_id = data[4:5]
                topology_type = data[5:13]
                nlri_offset = 13
                nlri_cur_pos = 0
                while nlri_offset < nlri_length:
                        tlv_type, tlv_length, tlv_value = decode_tlv(data, nlri_offset, 2, 2)
                        
                        if tlv_type == LSTLV.LOCAL_NODE_DESCRIPTORS:
                                node_length = tlv_length
                                node_offset = nlri_offset + 4
                                node_cur_pos = 0
                                while node_cur_pos < node_length:
                                        node_tlv_type, node_tlv_length, node_tlv_value = decode_tlv(data, node_offset, 2, 2)
                                        if node_tlv_type == LSTLV.IGP_ROUTER_ID:
                                                local_node_id = str(IP.unpack(node_tlv_value))
                                        if node_tlv_type == LSTLV.ASN:
                                                local_asn = str(int(binascii.hexlify(node_tlv_value), 16))
                                        node_offset = node_offset+2+2+node_tlv_length
                                        node_cur_pos = node_cur_pos+2+2+node_tlv_length
                                        
                        if tlv_type == LSTLV.REMOTE_NODE_DESCRIPTORS:
                                node_length = tlv_length
                                node_offset = nlri_offset + 4
                                node_cur_pos = 0
                                while node_cur_pos < node_length:
                                        node_tlv_type, node_tlv_length, node_tlv_value = decode_tlv(data, node_offset, 2, 2)
                                        if node_tlv_type == LSTLV.IGP_ROUTER_ID:
                                                print str(int(binascii.hexlify(node_tlv_value), 16))
                                                remote_node_id = str(IP.unpack(node_tlv_value))
                                        if node_tlv_type == LSTLV.ASN:
                                                remote_asn = str(int(binascii.hexlify(node_tlv_value), 16))
                                        node_offset = node_offset+2+2+node_tlv_length
                                        node_cur_pos = node_cur_pos+2+2+node_tlv_length
                                        
                        if tlv_type == LSTLV.LOCAL_IPV4:
                                local_ipv4 = str(IP.unpack(tlv_value))

                        if tlv_type == LSTLV.REMOTE_IPV4:
                                remote_ipv4 = str(IP.unpack(tlv_value))

                        nlri_offset = nlri_offset+2+2+tlv_length
                        nlri_cur_pos = nlri_cur_pos +2+2+tlv_length
                
                nlri = cls(local_node_id, local_asn, remote_node_id, remote_asn, local_ipv4, remote_ipv4, action)
                nlri.action = action
                if action == 1:
                    nlri.nexthop = IP.unpack(nexthop)
                return len(data), nlri
示例#22
0
文件: node.py 项目: gklinich/exabgp
    def unpack(cls, data, igp):
        node_type, length = unpack('!HH', data[0:4])
        packed = data[:4 + length]
        payload = packed[4:]
        remaining = data[4 + length:]

        node_id = None
        dr_id = None
        psn = None

        # autonomous-system
        if node_type == 512:
            if length != 4:
                raise Exception(cls._error_tlvs[node_type])
            node_id = unpack('!L', payload)[0]
            return cls(node_id, node_type, psn, dr_id, packed), remaining

        # bgp-ls-id
        if node_type == 513:
            if length != 4:
                raise Exception(cls._error_tlvs[node_type])
            node_id = unpack('!L', payload)[0]
            return cls(node_id, node_type, psn, dr_id, packed), remaining

        # ospf-area-id
        if node_type == 514:
            if length not in (4, 16):  # FIXME: it may only need to be 4
                raise Exception(cls._error_tlvs[node_type])
            node_id = IP.unpack(payload)
            return cls(node_id, node_type, psn, dr_id, packed), remaining

        # IGP Router-ID: The TLV size in combination with the protocol
        # identifier enables the decoder to determine the node_typee
        # of the node: sec 3.2.1.4.
        if node_type == 515:

            # IS-IS non-pseudonode
            if igp in (1, 2):
                if length not in (6, 7):
                    raise Exception(cls._error_tlvs[node_type])
                node_id = ISO.unpack_sysid(payload),
                if length == 7:
                    psn = unpack('!B', payload[6:7])[0]
                return cls(node_id, node_type, psn, dr_id, packed), remaining

            # OSPFv{2,3} non-pseudonode
            if igp in (3, 5, 6, 227):
                if length not in (4, 8):
                    raise Exception(cls._error_tlvs[node_type])
                node_id = IP.unpack(payload[:4]),
                if length == 8:
                    dr_id = IP.unpack(payload[4:8])
                return cls(node_id, node_type, psn, dr_id, packed), remaining

        raise Exception("unknown node descriptor sub-tlv ({}, {})".format(
            f'node-type: {node_type}',
            f'igp: {igp}',
        ))
示例#23
0
def attributes(tokeniser):
    ipmask = prefix(lambda: tokeniser.tokens[-1])

    if 'rd' in tokeniser.tokens or 'route-distinguisher' in tokeniser.tokens:
        nlri = IPVPN(IP.toafi(ipmask.top()), SAFI.mpls_vpn, OUT.ANNOUNCE)
    elif 'label' in tokeniser.tokens:
        nlri = Labelled(IP.toafi(ipmask.top()), SAFI.nlri_mpls, OUT.ANNOUNCE)
    else:
        nlri = INET(IP.toafi(ipmask.top()), IP.tosafi(ipmask.top()),
                    OUT.ANNOUNCE)

    nlri.cidr = CIDR(ipmask.pack(), ipmask.mask)

    change = Change(nlri, Attributes())

    while True:
        command = tokeniser()

        if not command:
            return []

        if command == 'nlri':
            break

        action = ParseStatic.action[command]

        if action == 'attribute-add':
            change.attributes.add(ParseStatic.known[command](tokeniser))
        elif action == 'nlri-set':
            change.nlri.assign(ParseStatic.assign[command],
                               ParseStatic.known[command](tokeniser))
        elif action == 'nexthop-and-attribute':
            nexthop, attribute = ParseStatic.known[command](tokeniser)
            change.nlri.nexthop = nexthop
            change.attributes.add(attribute)
        else:
            raise ValueError('route: unknown command "%s"' % command)

    attributes = change.attributes
    nexthop = change.nlri.nexthop

    changes = []
    while True:
        nlri = tokeniser.peek()
        if not nlri:
            break

        ipmask = prefix(tokeniser)
        new = Change(
            change.nlri.__class__(change.nlri.afi, change.nlri.safi,
                                  OUT.UNSET), attributes)
        new.nlri.cidr = CIDR(ipmask.pack(), ipmask.mask)
        new.nlri.nexthop = nexthop
        changes.append(new)

    return changes
示例#24
0
	def unpack (cls,data,length):
		if len(data) == 4:
    		# IPv4 address
			addr = IP.unpack(data[:4])
		elif len(data) == 16:
    		# IPv6
			addr = IP.unpack(data[:16])
		else:
			raise Notify(3,5, "Error parsing OSPF Forwarding Address. Wrong size")
		return cls(addr=addr)
示例#25
0
def MD5(io, ip, port, md5):
    if md5:
        os = platform.system()
        if os == 'FreeBSD':
            if md5 != 'kernel':
                raise MD5Error(
                    'FreeBSD requires that you set your MD5 key via ipsec.conf.\n'
                    'Something like:\n'
                    'flush;\n'
                    'add <local ip> <peer ip> tcp 0x1000 -A tcp-md5 "password";'
                )
            try:
                TCP_MD5SIG = 0x10
                io.setsockopt(socket.IPPROTO_TCP, TCP_MD5SIG, 1)
            except socket.error:
                raise MD5Error(
                    'FreeBSD requires that you rebuild your kernel to enable TCP MD5 Signatures:\n'
                    'options         IPSEC\n'
                    'options         TCP_SIGNATURE\n'
                    'device          crypto\n')
        elif os == 'Linux':
            try:
                # __kernel_sockaddr_storage
                n_af = IP.toaf(ip)
                n_addr = IP.pton(ip)
                n_port = socket.htons(port)

                # pack 'x' is padding, so we want the struct
                # Do not use '!' for the pack, the network (big) endian switch in
                # struct.pack is fighting against inet_pton and htons (note the n)

                if IP.toafi(ip) == AFI.ipv4:
                    # SS_MAXSIZE is 128 but addr_family, port and ipaddr (8 bytes total) are written independently of the padding
                    SS_MAXSIZE_PADDING = 128 - calcsize('HH4s')  # 8
                    sockaddr = pack('HH4s%dx' % SS_MAXSIZE_PADDING,
                                    socket.AF_INET, n_port, n_addr)
                else:
                    SS_MAXSIZE_PADDING = 128 - calcsize('HI16sI')  # 28
                    SIN6_FLOWINFO = 0
                    SIN6_SCOPE_ID = 0
                    sockaddr = pack('HHI16sI%dx' % SS_MAXSIZE_PADDING, n_af,
                                    n_port, SIN6_FLOWINFO, n_addr,
                                    SIN6_SCOPE_ID)

                TCP_MD5SIG_MAXKEYLEN = 80
                key = pack('2xH4x%ds' % TCP_MD5SIG_MAXKEYLEN, len(md5), md5)

                TCP_MD5SIG = 14
                io.setsockopt(socket.IPPROTO_TCP, TCP_MD5SIG, sockaddr + key)
            except socket.error, exc:
                raise MD5Error(
                    'This linux machine does not support TCP_MD5SIG, you can not use MD5 (%s)'
                    % errstr(exc))
        else:
            raise MD5Error('ExaBGP has no MD5 support for %s' % os)
示例#26
0
 def unpack(cls, data, length):
     if len(data) == 4:
         # IPv4 address
         addr = IP.unpack(data[:4])
     elif len(data) == 16:
         # IPv6
         addr = IP.unpack(data[:16])
     else:
         raise Notify(3, 5,
                      "Error parsing OSPF Forwarding Address. Wrong size")
     return cls(addr=addr)
示例#27
0
def prefix(tokeniser):
    # XXX: could raise
    ip = tokeniser()
    try:
        ip, mask = ip.split('/')
        mask = int(mask)
    except ValueError:
        mask = 32

    tokeniser.afi = IP.toafi(ip)
    return Range(ip, IP.pton(ip), mask)
示例#28
0
def redirect(tokeniser):
    data = tokeniser()
    count = data.count(':')
    if count == 0:
        return IP.create(data), ExtendedCommunities().add(
            TrafficNextHopSimpson(False))
    if count == 1:
        prefix, suffix = data.split(':', 1)
        if prefix.count('.'):
            raise ValueError(
                'this format has been deprecated as it does not make sense and it is not supported by other vendors'
            )

        asn = int(prefix)
        route_target = int(suffix)

        if asn >= pow(2, 32):
            raise ValueError('asn is a 32 bits number, value too large %s' %
                             asn)
        if asn >= pow(2, 16):
            if route_target >= pow(2, 16):
                raise ValueError(
                    'asn is a 32 bits number, route target can only be 16 bit %s'
                    % route_target)
            return NoNextHop, ExtendedCommunities().add(
                TrafficRedirectASN4(asn, route_target))
        if route_target >= pow(2, 32):
            raise ValueError(
                'route target is a 32 bits number, value too large %s' %
                route_target)
        return NoNextHop, ExtendedCommunities().add(
            TrafficRedirect(asn, route_target))
    else:
        explicit_v6 = ']:' in data

        # ipv4
        if not explicit_v6 and data.count(':') == 1:
            return IP.create(data), ExtendedCommunities().add(
                TrafficNextHopSimpson(False))

        # ipv6 using []: notation
        if explicit_v6:
            ip, asn = data.split(']:')
            ip = ip.replace('[', '', 1)
            # FIXME: should this be 2^16 ??
            if asn >= pow(2, 32):
                raise ValueError(
                    'asn is a 32 bits number, value too large %s' % asn)
            return IP.create(ip), ExtendedCommunities().add(
                TrafficRedirectIPv6(ip, asn))

        raise ValueError(
            'it looks like you tried to use an IPv6 but did not enclose it in []'
        )
示例#29
0
 def unpack(cls, data, igp):
     dtype, dlength = unpack('!HH', data[0:4])
     if dtype not in NODE_TLVS.keys():
         raise Exception("Unknown Node Descriptor Sub-TLV")
     # OSPF Area-ID
     if dtype == 514:
         return cls(node_id=IP.unpack(data[4:4 + dlength]),
                    dtype=dtype,
                    packed=data[:4 + dlength]), data[4 + dlength:]
     # IGP Router-ID: The TLV size in combination with the protocol
     # identifier enables the decoder to determine the type
     # of the node: sec 3.2.1.4.
     elif dtype == 515:
         # OSPFv{2,3} non-pseudonode
         if (igp == 3 or igp == 6) and dlength == 4:
             r_id = IP.unpack(data[4:4 + 4])
             return cls(node_id=r_id,
                        dtype=dtype,
                        packed=data[:4 + dlength]), data[4 + 4:]
         # OSPFv{2,3} LAN pseudonode
         if (igp == 3 or igp == 6) and dlength == 8:
             r_id = IP.unpack(data[4:4 + 4])
             dr_id = IP.unpack(data[8:4 + 8])
             return cls(node_id=r_id,
                        dtype=dtype,
                        psn=None,
                        dr_id=dr_id,
                        packed=data[:4 + dlength]), data[4 + 8:]
         # IS-IS non-pseudonode
         if (igp == 1 or igp == 2) and dlength == 6:
             return cls(node_id=ISO.unpack_sysid(data[4:4 + 6]),
                        dtype=dtype,
                        packed=data[:4 + dlength]), data[4 + 6:]
         # IS-IS LAN pseudonode = ISO Node-ID + PSN
         # Unpack ISO address
         if (igp == 1 or igp == 2) and dlength == 7:
             iso_node = ISO.unpack_sysid(data[4:4 + 6])
             psn = unpack('!B', data[4 + 6:4 + 7])[0]
             return cls(node_id=iso_node,
                        dtype=dtype,
                        psn=psn,
                        packed=data[:4 + dlength]), data[4 + 7:]
     elif dtype == 512 and dlength == 4:
         # ASN
         return cls(node_id=unpack('!L', data[4:4 + dlength])[0],
                    dtype=dtype,
                    packed=data[:4 + dlength]), data[4 + 4:]
     elif dtype == 513 and dlength == 4:
         # BGP-LS
         return cls(node_id=unpack('!L', data[4:4 + dlength])[0],
                    dtype=dtype,
                    packed=data[:4 + dlength]), data[4 + 4:]
     else:
         raise Notify(3, 5, 'could not decode Local Node descriptor')
示例#30
0
def prefix (tokeniser):
	# XXX: could raise
	ip = tokeniser()
	try:
		ip,mask = ip.split('/')
		mask = int(mask)
	except ValueError:
		mask = 32

	tokeniser.afi = IP.toafi(ip)
	return Range(ip,IP.pton(ip),mask)
示例#31
0
def route (tokeniser):
	action = OUT.ANNOUNCE if tokeniser.announce else OUT.WITHDRAW
	ipmask = prefix(tokeniser)
	check = lambda change,afi: True

	if 'rd' in tokeniser.tokens or 'route-distinguisher' in tokeniser.tokens:
		nlri = IPVPN(IP.toafi(ipmask.top()),SAFI.mpls_vpn,action)
		check = AnnounceVPN.check
	elif 'label' in tokeniser.tokens:
		nlri = Label(IP.toafi(ipmask.top()),SAFI.nlri_mpls,action)
		check = AnnounceLabel.check
	else:
		nlri = INET(IP.toafi(ipmask.top()), IP.tosafi(ipmask.top()), action)
		check = AnnouncePath.check

	nlri.cidr = CIDR(ipmask.pack(),ipmask.mask)

	change = Change(
		nlri,
		Attributes()
	)

	while True:
		command = tokeniser()

		if not command:
			break

		if command == 'label':
			nlri.labels = label(tokeniser)
			continue

		if command == 'rd' or command == 'route-distinguisher':
			nlri.rd = route_distinguisher(tokeniser)
			continue

		action = ParseStatic.action.get(command,'')

		if action == 'attribute-add':
			change.attributes.add(ParseStatic.known[command](tokeniser))
		elif action == 'nlri-set':
			change.nlri.assign(ParseStatic.assign[command],ParseStatic.known[command](tokeniser))
		elif action == 'nexthop-and-attribute':
			nexthop,attribute = ParseStatic.known[command](tokeniser)
			change.nlri.nexthop = nexthop
			change.attributes.add(attribute)
		else:
			raise ValueError('unknown command "%s"' % command)

	if not check(change,nlri.afi):
		raise ValueError('invalid route (missing next-hop, label or rd ?)')

	return list(ParseStatic.split(change))
示例#32
0
文件: parser.py 项目: pierky/exabgp
def destination(tokeniser):
    data = tokeniser()
    if data.count('.') == 3 and data.count(':') == 0:
        ip, netmask = data.split('/')
        raw = b''.join(bytes([int(_)]) for _ in ip.split('.'))
        yield Flow4Destination(raw, int(netmask))
    elif data.count('/') == 1:
        ip, netmask = data.split('/')
        offset = 0
        yield Flow6Destination(IP.pton(ip), int(netmask), int(offset))
    else:
        ip, netmask, offset = data.split('/')
        yield Flow6Destination(IP.pton(ip), int(netmask), int(offset))
示例#33
0
def inet (tokeniser):
	ipmask = prefix(tokeniser)
	inet = INET(
		afi=IP.toafi(ipmask.top()),
		safi=IP.tosafi(ipmask.top()),
		action=OUT.UNSET
	)
	inet.cidr = CIDR(ipmask.ton(),ipmask.mask)

	return Change(
		inet,
		Attributes()
	)
示例#34
0
def mpls (tokeniser):
	ipmask = prefix(tokeniser)
	mpls = IPVPN(
		afi=IP.toafi(ipmask.top()),
		safi=IP.tosafi(ipmask.top()),
		action=OUT.UNSET
	)
	mpls.cidr = CIDR(ipmask.ton(),ipmask.mask)

	return Change(
		mpls,
		Attributes()
	)
示例#35
0
def destination(tokeniser):
    data = tokeniser()
    if data.count('.') == 3 and data.count(':') == 0:
        ip, netmask = data.split('/')
        raw = concat_bytes_i(character(int(_)) for _ in ip.split('.'))
        yield Flow4Destination(raw, int(netmask))
    elif data.count('/') == 1:
        ip, netmask = data.split('/')
        offset = 0
        yield Flow6Destination(IP.pton(ip), int(netmask), int(offset))
    else:
        ip, netmask, offset = data.split('/')
        yield Flow6Destination(IP.pton(ip), int(netmask), int(offset))
示例#36
0
def source(tokeniser):
    data = tokeniser()
    if data.count('.') == 3 and data.count(':') == 0:
        ip, netmask = data.split('/')
        raw = ''.join(chr(int(_)) for _ in ip.split('.'))
        yield Flow4Source(raw, int(netmask))
    elif data.count('/') == 1:
        ip, netmask = data.split('/')
        offset = 0
        yield Flow6Source(IP.pton(ip), int(netmask), int(offset))
    else:
        ip, netmask, offset = data.split('/')
        yield Flow6Source(IP.pton(ip), int(netmask), int(offset))
示例#37
0
def inet (tokeniser):
	ipmask = prefix(tokeniser)
	return Change(
		INET(
			afi=IP.toafi(ipmask.string),
			safi=IP.tosafi(ipmask.string),
			packed=IP.pton(ipmask.string),
			mask=ipmask.mask,
			nexthop=None,
			action=OUT.UNSET
		),
		Attributes()
	)
示例#38
0
文件: parser.py 项目: dhammika/exabgp
def destination (tokeniser):
	data = tokeniser()
	if data.count('.') == 3 and data.count(':') == 0:
		ip,netmask = data.split('/')
		raw = concat_bytes_i(character(int(_)) for _ in ip.split('.'))
		yield Flow4Destination(raw,int(netmask))
	elif data.count('/') == 1:
		ip,netmask = data.split('/')
		offset = 0
		yield Flow6Destination(IP.pton(ip),int(netmask),int(offset))
	else:
		ip,netmask,offset = data.split('/')
		yield Flow6Destination(IP.pton(ip),int(netmask),int(offset))
示例#39
0
	def listen_on (self, local_addr, remote_addr, port, md5_password, md5_base64, ttl_in):
		try:
			if not remote_addr:
				remote_addr = IP.create('0.0.0.0') if local_addr.ipv4() else IP.create('::')
			self._listen(local_addr, remote_addr, port, md5_password, md5_base64, ttl_in)
			self.logger.debug('listening for BGP session(s) on %s:%d%s' % (local_addr, port,' with MD5' if md5_password else ''),'network')
			return True
		except NetworkError as exc:
			if os.geteuid() != 0 and port <= 1024:
				self.logger.critical('can not bind to %s:%d, you may need to run ExaBGP as root' % (local_addr, port),'network')
			else:
				self.logger.critical('can not bind to %s:%d (%s)' % (local_addr, port,str(exc)),'network')
			self.logger.critical('unset exabgp.tcp.bind if you do not want listen for incoming connections','network')
			self.logger.critical('and check that no other daemon is already binding to port %d' % port,'network')
			return False
示例#40
0
    def test101_EVPNHashEqual_somefieldsvary(self):
        '''
        Two EVPN MAC NLRIs differing by their ESI or label or RD,
        or nexthop, but otherwise identical should hash to the same value,
        and be equal
        '''

        nlri0 = EVPNMAC(RouteDistinguisher.fromElements("42.42.42.42",
                                                        5), ESI(),
                        EthernetTag(111), MAC("01:02:03:04:05:06"), 6 * 8,
                        Labels([42], True), IP.create("1.1.1.1"))

        # Esi
        nlri1 = EVPNMAC(RouteDistinguisher.fromElements("42.42.42.42", 5),
                        ESI(['1' for _ in range(0, 10)]), EthernetTag(111),
                        MAC("01:02:03:04:05:06"), 6 * 8, Labels([42], True),
                        IP.create("1.1.1.1"))

        # label
        nlri2 = EVPNMAC(RouteDistinguisher.fromElements("42.42.42.42",
                                                        5), ESI(),
                        EthernetTag(111), MAC("01:02:03:04:05:06"), 6 * 8,
                        Labels([4444], True), IP.create("1.1.1.1"))

        # IP: different IPs, but same MACs: different route
        nlri3 = EVPNMAC(RouteDistinguisher.fromElements("42.42.42.42",
                                                        5), ESI(),
                        EthernetTag(111), MAC("01:02:03:04:05:06"), 6 * 8,
                        Labels([42], True), IP.create("2.2.2.2"))

        # with a next hop...
        nlri4 = EVPNMAC(RouteDistinguisher.fromElements("42.42.42.42",
                                                        5), ESI(),
                        EthernetTag(111), MAC("01:02:03:04:05:06"), 6 * 8,
                        Labels([42], True), IP.create("1.1.1.1"),
                        IP.pton("10.10.10.10"))
        nlri5 = EVPNMAC(RouteDistinguisher.fromElements("42.42.42.42",
                                                        5), ESI(),
                        EthernetTag(111), MAC("01:02:03:04:05:06"), 6 * 8,
                        Labels([42], True), IP.create("1.1.1.1"),
                        IP.pton("11.11.11.11"))

        self.assertEqual(hash(nlri0), hash(nlri1))
        self.assertEqual(hash(nlri0), hash(nlri2))
        self.assertEqual(hash(nlri0), hash(nlri4))
        self.assertEqual(nlri0, nlri1)
        self.assertEqual(nlri0, nlri2)
        self.assertEqual(nlri0, nlri4)
        self.assertEqual(nlri1, nlri2)
        self.assertEqual(nlri1, nlri4)
        self.assertEqual(nlri2, nlri4)
        self.assertEqual(nlri4, nlri5)

        self.assertNotEqual(hash(nlri0), hash(nlri3))
        self.assertNotEqual(nlri0, nlri3)
        self.assertNotEqual(nlri1, nlri3)
        self.assertNotEqual(nlri2, nlri3)
        self.assertNotEqual(nlri3, nlri4)
示例#41
0
文件: lterid.py 项目: gklinich/exabgp
    def unpack(cls, data):
        length = len(data)

        if length not in (4, 16):
            raise Notify(3, 5, "Invalid remote-te size")

        return cls([str(IP.unpack(data))])
示例#42
0
    def connect(self):
        # allows to test the protocol code using modified StringIO with a extra 'pending' function
        if not self.connection:
            local = self.neighbor.md5_ip.top(
            ) if not self.neighbor.auto_discovery else None
            peer = self.neighbor.peer_address.top()
            afi = self.neighbor.peer_address.afi
            md5 = self.neighbor.md5_password
            md5_base64 = self.neighbor.md5_base64
            ttl_out = self.neighbor.ttl_out
            self.connection = Outgoing(afi, peer, local, self.port, md5,
                                       md5_base64, ttl_out)
            if not local and self.connection.init:
                self.neighbor.local_address = IP.create(self.connection.local)
                if self.neighbor.router_id is None and self.neighbor.local_address.afi == AFI.ipv4:
                    self.neighbor.router_id = self.neighbor.local_address

            try:
                generator = self.connection.establish()
                while True:
                    connected = six.next(generator)
                    if not connected:
                        yield False
                        continue
                    if self.peer.neighbor.api['neighbor-changes']:
                        self.peer.reactor.processes.connected(
                            self.peer.neighbor)
                    yield True
                    return
            except StopIteration:
                # close called by the caller
                # self.close('could not connect to remote end')
                yield False
                return
示例#43
0
    def connect(self):
        # allows to test the protocol code using modified StringIO with a extra 'pending' function
        if self.connection:
            return

        local = self.neighbor['md5-ip'].top(
        ) if not self.neighbor.auto_discovery else None
        peer = self.neighbor['peer-address'].top()
        afi = self.neighbor['peer-address'].afi
        md5 = self.neighbor['md5-password']
        md5_base64 = self.neighbor['md5-base64']
        ttl_out = self.neighbor['outgoing-ttl']
        self.connection = Outgoing(afi, peer, local, self.port, md5,
                                   md5_base64, ttl_out)

        for connected in self.connection.establish():
            yield False

        if self.peer.neighbor.api['neighbor-changes']:
            self.peer.reactor.processes.connected(self.peer.neighbor)

        if not local:
            self.neighbor['local-address'] = IP.create(self.connection.local)
            if self.neighbor['router-id'] is None and self.neighbor[
                    'local-address'].afi == AFI.ipv4:
                self.neighbor['router-id'] = self.neighbor['local-address']

        yield True
示例#44
0
	def connect (self):
		# allows to test the protocol code using modified StringIO with a extra 'pending' function
		if not self.connection:
			local = self.neighbor.md5_ip.top() if not self.neighbor.auto_discovery else None
			peer = self.neighbor.peer_address.top()
			afi = self.neighbor.peer_address.afi
			md5 = self.neighbor.md5_password
			md5_base64 = self.neighbor.md5_base64
			ttl_out = self.neighbor.ttl_out
			self.connection = Outgoing(afi,peer,local,self.port,md5,md5_base64,ttl_out)
			if not self.connection.init:
				yield False
				return
			if not local:
				self.neighbor.local_address = IP.create(self.connection.local)
				if self.neighbor.router_id is None and self.neighbor.local_address.afi == AFI.ipv4:
					self.neighbor.router_id = self.neighbor.local_address

			for connected in self.connection.establish():
				if not connected:
					yield False
					continue
				if self.peer.neighbor.api['neighbor-changes']:
					self.peer.reactor.processes.connected(self.peer.neighbor)
				yield True
				return
示例#45
0
文件: flow.py 项目: Shmuma/exabgp
	def redirect (self, scope, name, command, tokens):
		try:
			if tokens[0].count(':') == 1:
				prefix,suffix = tokens[0].split(':',1)
				if prefix.count('.'):
					raise ValueError('this format has been deprecaded as it does not make sense and it is not supported by other vendors')
				else:
					asn = int(prefix)
					route_target = int(suffix)
					if asn >= pow(2,16):
						raise ValueError('asn is a 32 bits number, it can only be 16 bit %s' % route_target)
					if route_target >= pow(2,32):
						raise ValueError('route target is a 32 bits number, value too large %s' % route_target)
					scope[-1]['announce'][-1].attributes[Attribute.CODE.EXTENDED_COMMUNITY].add(TrafficRedirect(asn,route_target))
					return True
			else:
				change = scope[-1]['announce'][-1]
				if change.nlri.nexthop is not NoNextHop:
					return self.error.set(self.syntax)

				nh = IP.create(tokens.pop(0))
				change.nlri.nexthop = nh
				change.attributes[Attribute.CODE.EXTENDED_COMMUNITY].add(TrafficNextHop(False))
				return True

		except (IndexError,ValueError):
			return self.error.set(self.syntax)
示例#46
0
	def _multi_neighbor (self, scope, tokens):
		if len(tokens) != 1:
			return self.error.set('syntax: neighbor <ip> { <options> }')

		address = tokens[0]
		scope.append({})
		try:
			scope[-1]['peer-address'] = IP.create(address)
		except (IndexError,ValueError,socket.error):
			return self.error.set('"%s" is not a valid IP address' % address)

		while True:
			r = self._dispatch(
				scope,'neighbor',
				[
					'static','flow','l2vpn',
					'process','family','capability','operational'
				],
				[
					'description','router-id','local-address','local-as','peer-as',
					'host-name','domain-name',
					'passive','listen','hold-time','add-path','graceful-restart','md5',
					'ttl-security','multi-session','group-updates','asn4','aigp',
					'auto-flush','adj-rib-out'
				]
			)
			# XXX: THIS SHOULD ALLOW CAPABILITY AND NOT THE INDIVIDUAL SUB KEYS
			if r is False:
				return False
			if r is None:
				return True
示例#47
0
    def test200_IPVPNCreatePackUnpack(self):
        '''Test pack/unpack for IPVPN routes'''
        nlri = IPVPN.new(
            AFI.ipv4,
            SAFI.mpls_vpn,
            IP.pton("1.2.3.0"),
            24,
            Labels([42], True),
            RouteDistinguisher.fromElements("42.42.42.42", 5),
        )

        packed = nlri.pack()
        unpacked, leftover = IPVPN.unpack_nlri(AFI.ipv4, SAFI.mpls_vpn, packed,
                                               OUT.UNSET, None)

        self.assertEqual(0, len(leftover))

        # TODO: compare packed with a reference encoding verified
        # as conformant with RFC4364

        self.assertTrue(isinstance(unpacked, IPVPN))

        self.assertEqual("1.2.3.0/24", unpacked.cidr.prefix())
        self.assertEqual(1, len(unpacked.labels.labels))
        self.assertEqual(42, unpacked.labels.labels[0])
        self.assertEqual("42.42.42.42:5", unpacked.rd._str())
示例#48
0
文件: __init__.py 项目: Shmuma/exabgp
	def _multi_neighbor (self, scope, name, command, tokens):
		if len(tokens) != 1:
			return self.error.set('syntax: neighbor <ip> { <options> }')

		address = tokens[0]
		scope.append({})
		try:
			scope[-1]['peer-address'] = IP.create(address)
		except (IndexError,ValueError,socket.error):
			return self.error.set('"%s" is not a valid IP address' % address)

		while True:
			r = self._dispatch(
				scope,name,'neighbor',
				[
					'static','flow','l2vpn',
					'process','family','capability','operational'
				],
				self._command['neighbor']
			)
			# XXX: THIS SHOULD ALLOW CAPABILITY AND NOT THE INDIVIDUAL SUB KEYS
			if r is False:
				return False
			if r is None:
				return True
示例#49
0
文件: mpls.py 项目: asnd/exabgp
	def __init__(self,afi,safi,packed,mask,nexthop,action):
		self.labels = Labels.NOLABEL
		self.rd = RouteDistinguisher.NORD
		self.nexthop = IP.unpack(nexthop) if nexthop else NoIP
		self.action = action
		NLRI.__init__(self,afi,safi)
		CIDR.__init__(self,packed,mask)
示例#50
0
    def unpack(cls, data, length):
        size = len(data)

        if size not in (4, 16):
            raise Notify(3, 5, "Invalid remote-te size")

        return cls([str(IP.unpack(data[:size]))])
示例#51
0
	def __init__ (self, afi=AFI.ipv4,safi=SAFI.flow_ip,nexthop=None,rd=None):
		NLRI.__init__(self,afi,safi)
		self.rules = {}
		self.action = OUT.UNSET
		self.nexthop = IP.unpack(nexthop) if nexthop else NoNextHop
		self.rd = rd if rd else RouteDistinguisher.NORD
		self.unique = unique.next()
示例#52
0
文件: protocol.py 项目: aabdnn/exabgp
	def connect (self):
		# allows to test the protocol code using modified StringIO with a extra 'pending' function
		if not self.connection:
			local = self.neighbor.md5_ip.top() if not self.neighbor.auto_discovery else None
			peer = self.neighbor.peer_address.top()
			afi = self.neighbor.peer_address.afi
			md5 = self.neighbor.md5_password
			md5_base64 = self.neighbor.md5_base64
			ttl_out = self.neighbor.ttl_out
			self.connection = Outgoing(afi,peer,local,self.port,md5,md5_base64,ttl_out)
			if not local and self.connection.init:
				self.neighbor.local_address = IP.create(self.connection.local)
				if self.neighbor.router_id is None and self.neighbor.local_address.afi == AFI.ipv4:
					self.neighbor.router_id = self.neighbor.local_address

			try:
				generator = self.connection.establish()
				while True:
					connected = six.next(generator)
					if not connected:
						yield False
						continue
					if self.peer.neighbor.api['neighbor-changes']:
						self.peer.reactor.processes.connected(self.peer.neighbor)
					yield True
					return
			except StopIteration:
				# close called by the caller
				# self.close('could not connect to remote end')
				yield False
				return
示例#53
0
文件: mac.py 项目: Akheon23/exabgp
	def unpack (cls, data):
		datalen = len(data)
		rd = RouteDistinguisher.unpack(data[:8])
		esi = ESI.unpack(data[8:18])
		etag = EthernetTag.unpack(data[18:22])
		maclength = ord(data[22])

		if (maclength > 48 or maclength < 0):
			raise Notify(3,5,'invalid MAC Address length in %s' % cls.NAME)
		end = 23 + 6 # MAC length MUST be 6

		mac = MACQUAL.unpack(data[23:end])

		length = ord(data[end])
		iplen = length / 8

		if datalen in [36,39]:  # No IP information (1 or 2 labels)
			iplenUnpack = 0
			if iplen != 0:
				raise Notify(3,5,"IP length is given as %d, but current MAC route has no IP information" % iplen)
		elif datalen in [40, 43]:  # Using IPv4 addresses (1 or 2 labels)
			iplenUnpack = 4
			if (iplen > 32 or iplen < 0):
				raise Notify(3,5,"IP field length is given as %d, but current MAC route is IPv4 and valus is out of range" % iplen)
		elif datalen in [52, 55]:  # Using IPv6 addresses (1 or 2 labels)
			iplenUnpack = 16
			if (iplen > 128 or iplen < 0):
				raise Notify(3,5,"IP field length is given as %d, but current MAC route is IPv6 and valus is out of range" % iplen)
		else:
			raise Notify(3,5,"Data field length is given as %d, but does not match one of the expected lengths" % datalen)

		ip = IP.unpack(data[end+1:end+1+iplenUnpack])
		label = Labels.unpack(data[end+1+iplenUnpack:end+1+iplenUnpack+3])

		return cls(rd,esi,etag,mac,maclength,label,ip,data)
示例#54
0
    def connect(self):
        # allows to test the protocol code using modified StringIO with a extra 'pending' function
        if not self.connection:
            local = self.neighbor.md5_ip.top(
            ) if not self.neighbor.auto_discovery else None
            peer = self.neighbor.peer_address.top()
            afi = self.neighbor.peer_address.afi
            md5 = self.neighbor.md5_password
            md5_base64 = self.neighbor.md5_base64
            ttl_out = self.neighbor.ttl_out
            self.connection = Outgoing(afi, peer, local, self.port, md5,
                                       md5_base64, ttl_out)
            if not self.connection.init:
                yield False
                return
            if not local:
                self.neighbor.local_address = IP.create(self.connection.local)
                if self.neighbor.router_id is None and self.neighbor.local_address.afi == AFI.ipv4:
                    self.neighbor.router_id = self.neighbor.local_address

            for connected in self.connection.establish():
                if not connected:
                    yield False
                    continue
                if self.peer.neighbor.api['neighbor-changes']:
                    self.peer.reactor.processes.connected(self.peer.neighbor)
                yield True
                return
示例#55
0
	def __init__ (self,afi=AFI.ipv4,safi=SAFI.flow_ip,nexthop=None,rd=None):
		NLRI.__init__(self,afi,safi)
		self.rules = {}
		self.action = OUT.announce
		self.nexthop = IP.unpack(nexthop) if nexthop else NoIP
		self.rd = rd
		self.unique = unique.next()
示例#56
0
 def __init__(self, afi=AFI.ipv4, safi=SAFI.flow_ip, nexthop=None, rd=None):
     NLRI.__init__(self, afi, safi)
     self.rules = {}
     self.action = OUT.ANNOUNCE
     self.nexthop = IP.unpack(nexthop) if nexthop else NoIP
     self.rd = rd
     self.unique = unique.next()
示例#57
0
文件: mpls.py 项目: Shmuma/exabgp
	def __init__ (self, afi, safi, packed, mask, nexthop, action,path=None):
		self.path_info = PathInfo.NOPATH if path is None else path
		self.labels = Labels.NOLABEL
		self.rd = RouteDistinguisher.NORD
		self.nexthop = IP.unpack(nexthop) if nexthop else NoNextHop
		self.action = action
		NLRI.__init__(self,afi,safi)
		CIDR.__init__(self,packed,mask)
示例#58
0
def route (tokeniser):
	ipmask = prefix(tokeniser)

	if 'rd' in tokeniser.tokens or 'route-distinguisher' in tokeniser.tokens:
		klass = MPLS
		safi = SAFI(SAFI.mpls_vpn)
	elif 'label' in tokeniser.tokens:
		# XXX: should we create a LABEL class ?
		klass = MPLS
		safi = SAFI(SAFI.nlri_mpls)
	else:
		klass = INET
		safi = IP.tosafi(ipmask.string)

	change = Change(
		klass(
			IP.toafi(ipmask.string),
			safi,
			ipmask.pack(),
			ipmask.mask,
			'',
			OUT.UNSET
		),
		Attributes()
	)

	while True:
		command = tokeniser()

		if not command:
			break

		action = ParseStatic.action[command]

		if action == 'attribute-add':
			change.attributes.add(ParseStatic.known[command](tokeniser))
		elif action == 'nlri-set':
			change.nlri.assign(ParseStatic.assign[command],ParseStatic.known[command](tokeniser))
		elif action == 'nexthop-and-attribute':
			nexthop,attribute = ParseStatic.known[command](tokeniser)
			change.nlri.nexthop = nexthop
			change.attributes.add(attribute)
		else:
			raise ValueError('route: unknown command "%s"' % command)

	return list(ParseStatic.split(change))
示例#59
0
	def ip (self, scope, command, tokens):
		try:
			ip = IP.create(tokens[0])
		except (IndexError,ValueError):
			return self.error.set('"%s" is an invalid IP address' % ' '.join(tokens))

		scope[-1][command] = ip
		return True