예제 #1
0
    def setUp(self):
        # env.log.all = True
        self.negotiated = {}

        for asn4 in (True, False):
            neighbor = Neighbor()
            neighbor.asn4 = asn4

            capa = Capabilities().new(neighbor, False)
            capa[Capability.CODE.MULTIPROTOCOL] = neighbor.families()

            # path = {}
            # for f in known_families():
            # 	if neighbor.add_path:
            # 		path[f] = neighbor.add_path
            # capa[Capability.CODE.ADD_PATH] = path

            o1 = Open(4, neighbor.local_as, '127.0.0.1', capa, 180)
            o2 = Open(4, neighbor.peer_as, '127.0.0.1', capa, 180)

            negotiated = Negotiated(neighbor)
            negotiated.sent(o1)
            negotiated.received(o2)

            self.negotiated[asn4] = negotiated
예제 #2
0
def check_update (neighbor, raw):
	from exabgp.logger import Logger

	logger = Logger()
	logger._parser = True
	logger.parser('\ndecoding routes in configuration')

	n = neighbor[neighbor.keys()[0]]
	p = Peer(n,None)

	path = {}
	for f in known_families():
		if n.add_path:
			path[f] = n.add_path

	capa = Capabilities().new(n,False)
	capa[Capability.CODE.ADD_PATH] = path
	capa[Capability.CODE.MULTIPROTOCOL] = n.families()

	routerid_1 = str(n.router_id)
	routerid_2 = '.'.join(str((int(_)+1) % 250) for _ in str(n.router_id).split('.',-1))

	o1 = Open(4,n.local_as,routerid_1,capa,180)
	o2 = Open(4,n.peer_as,routerid_2,capa,180)
	negotiated = Negotiated(n)
	negotiated.sent(o1)
	negotiated.received(o2)
	# grouped = False

	while raw:
		if raw.startswith('\xff'*16):
			kind = ord(raw[18])
			size = (ord(raw[16]) << 16) + (ord(raw[17]))

			injected,raw = raw[19:size],raw[size:]

			if kind == 2:
				logger.parser('the message is an update')
				decoding = 'update'
			else:
				logger.parser('the message is not an update (%d) - aborting' % kind)
				return False
		else:
			logger.parser('header missing, assuming this message is ONE update')
			decoding = 'update'
			injected,raw = raw,''

		try:
			# This does not take the BGP header - let's assume we will not break that :)
			update = Update.unpack_message(injected,negotiated)
		except KeyboardInterrupt:
			raise
		except Notify,exc:
			logger.parser('could not parse the message','error')
			logger.parser(str(exc),'error')
			return False
		except Exception,exc:
			logger.parser('could not parse the message','error')
			logger.parser(str(exc),'error')
			return False
예제 #3
0
 def test_2_open(self):
     capabilities = Capabilities()
     o = Open(4, 65500, '127.0.0.1', capabilities, 180)
     self.assertEqual(o.version, 4)
     self.assertEqual(o.asn, 65500)
     self.assertEqual(o.router_id, RouterID('127.0.0.1'))
     self.assertEqual(o.hold_time, 180)
     self.assertEqual(o.capabilities, {})
예제 #4
0
    def new_open(self, restarted):
        sent_open = Open(4, self.neighbor.local_as, self.neighbor.router_id.ip,
                         Capabilities().new(self.neighbor, restarted),
                         self.neighbor.hold_time)

        # we do not buffer open message in purpose
        for _ in self.write(sent_open):
            yield _NOP

        self.logger.message(self.me('>> %s' % sent_open))
        yield sent_open
예제 #5
0
파일: __init__.py 프로젝트: fobser/exabgp
	def unpack_message (cls, data, _):
		version = ord(data[0])
		if version != 4:
			# Only version 4 is supported nowdays..
			raise Notify(2,1,data[0])
		asn = unpack('!H',data[1:3])[0]
		hold_time = unpack('!H',data[3:5])[0]
		numeric = unpack('!L',data[5:9])[0]
		router_id = "%d.%d.%d.%d" % (numeric >> 24,(numeric >> 16) & 0xFF,(numeric >> 8) & 0xFF,numeric & 0xFF)
		capabilities = Capabilities.unpack(data[9:])
		return cls(version,asn,router_id,capabilities,hold_time)
예제 #6
0
 def unpack_message(cls, data, _=None):
     version = ord(data[0])
     if version != 4:
         # Only version 4 is supported nowdays..
         raise Notify(2, 1, data[0])
     asn = unpack('!H', data[1:3])[0]
     hold_time = unpack('!H', data[3:5])[0]
     numeric = unpack('!L', data[5:9])[0]
     router_id = "%d.%d.%d.%d" % (numeric >> 24, (numeric >> 16) & 0xFF,
                                  (numeric >> 8) & 0xFF, numeric & 0xFF)
     capabilities = Capabilities.unpack(data[9:])
     return cls(version, asn, router_id, capabilities, hold_time)
예제 #7
0
    def new_open(self, restarted):
        sent_open = Open(4, self.neighbor.local_as, self.neighbor.router_id.ip,
                         Capabilities().new(self.neighbor, restarted),
                         self.neighbor.hold_time)

        # we do not buffer open message in purpose
        msg_send = sent_open.message()
        for _ in self.write(msg_send):
            yield _NOP

        self.logger.message(self.me('>> %s' % sent_open))
        if self.neighbor.api[Message.CODE.OPEN]:
            if self.neighbor.api['consolidate']:
                header = msg_send[0:38]
                body = msg_send[38:]
                self.peer.reactor.processes.message(Message.CODE.OPEN,
                                                    self.peer, sent_open,
                                                    header, body, 'sent')
            else:
                self.peer.reactor.processes.message(Message.CODE.OPEN,
                                                    self.peer, sent_open, '',
                                                    '', 'sent')
        yield sent_open
예제 #8
0
def check_neighbor (neighbors):
	from exabgp.logger import Logger

	logger = Logger()
	logger._option.parser = True

	if not neighbors:
		logger.parser('\ncould not find neighbor(s) to check')
		return False

	logger.parser('\ndecoding routes in configuration')

	for name in neighbors.keys():
		neighbor = neighbors[name]

		path = {}
		for f in known_families():
			if neighbor.add_path:
				path[f] = neighbor.add_path

		capa = Capabilities().new(neighbor,False)
		if path:
			capa[Capability.CODE.ADD_PATH] = path
		capa[Capability.CODE.MULTIPROTOCOL] = neighbor.families()

		o1 = Open(4,neighbor.local_as,'127.0.0.2',capa,180)
		o2 = Open(4,neighbor.peer_as,'127.0.0.3',capa,180)
		negotiated = Negotiated(neighbor)
		negotiated.sent(o1)
		negotiated.received(o2)
		# grouped = False

		for message in neighbor.rib.outgoing.updates(False):
			pass

		for change1 in neighbor.rib.outgoing.sent_changes():
			str1 = change1.extensive()
			packed = list(Update([change1.nlri],change1.attributes).messages(negotiated))
			pack1 = packed[0]

			logger.parser('parsed route requires %d updates' % len(packed))
			logger.parser('parsed route requires %d updates' % len(packed))
			logger.parser('update size is %d' % len(pack1))

			logger.parser('parsed route %s' % str1)
			logger.parser('parsed hex   %s' % od(pack1))

			# This does not take the BGP header - let's assume we will not break that :)
			try:
				logger.parser('')  # new line

				pack1s = pack1[19:] if pack1.startswith('\xFF'*16) else pack1
				update = Update.unpack_message(pack1s,negotiated)

				change2 = Change(update.nlris[0],update.attributes)
				str2 = change2.extensive()
				pack2 = list(Update([update.nlris[0]],update.attributes).messages(negotiated))[0]

				logger.parser('recoded route %s' % str2)
				logger.parser('recoded hex   %s' % od(pack2))

				str1r = str1.replace(' med 100','').replace(' local-preference 100','').replace(' origin igp','')
				str2r = str2.replace(' med 100','').replace(' local-preference 100','').replace(' origin igp','')

				if ' name ' in str1r:
					parts = str1r.split(' ')
					pos = parts.index('name')
					str1r = ' '.join(parts[:pos] + parts[pos+2:])

				skip = False

				if str1r != str2r:
					if 'attribute [' in str1r and ' 0x00 ' in str1r:
						# we do not decode non-transitive attributes
						logger.parser('skipping string check on update with non-transitive attribute(s)')
						skip = True
					else:
						logger.parser('strings are different:')
						logger.parser('[%s]' % (str1r))
						logger.parser('[%s]' % (str2r))
						return False
				else:
					logger.parser('strings are fine')

				if skip:
					logger.parser('skipping encoding for update with non-transitive attribute(s)')
				elif pack1 != pack2:
					logger.parser('encoding are different')
					logger.parser('[%s]' % (od(pack1)))
					logger.parser('[%s]' % (od(pack2)))
					return False
				else:
					logger.parser('encoding is fine')
					logger.parser('----------------------------------------')

				logger.parser('JSON nlri %s' % change1.nlri.json())
				logger.parser('JSON attr %s' % change1.attributes.json())

			except Notify,exc:
				logger.parser('----------------------------------------')
				logger.parser(str(exc))
				logger.parser('----------------------------------------')
				return False
		neighbor.rib.clear()