Beispiel #1
0
def check_update(neighbor, raw):
    option.enabled['parser'] = True
    negotiated = _negotiated(neighbor)

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

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

            if kind == 2:
                log.debug('the message is an update', 'parser')
                decoding = 'update'
            else:
                log.debug(
                    'the message is not an update (%d) - aborting' % kind,
                    'parser')
                return False
        else:
            log.debug('header missing, assuming this message is ONE update',
                      'parser')
            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, Direction.IN, negotiated)
        except Notify:
            import traceback

            log.error('could not parse the message', 'parser')
            log.error(traceback.format_exc(), 'parser')
            if getenv().debug.pdb:
                raise
            return False
        except Exception:
            import traceback

            log.error('could not parse the message', 'parser')
            log.error(traceback.format_exc(), 'parser')
            if getenv().debug.pdb:
                raise
            return False

        log.debug('', 'parser')  # new line
        for number in range(len(update.nlris)):
            change = Change(update.nlris[number], update.attributes)
            log.info(
                'decoded %s %s %s' %
                (decoding, change.nlri.action, change.extensive()), 'parser')
        log.info(
            'update json %s' % Response.JSON(json_version).update(
                neighbor, 'in', update, None, '', ''), 'parser')

    return True
Beispiel #2
0
def check_neighbor (neighbors):
	from exabgp.logger import Logger

	logger = Logger()
	logger._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]
		neighbor.rib.clear()

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

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

		o1 = Open(4,neighbor.local_as,str(neighbor.local_address),capa,180)
		o2 = Open(4,neighbor.peer_as,str(neighbor.peer_address),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('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('----------------------------------------')

			except Notify,exc:
				logger.parser('----------------------------------------')
				logger.parser(str(exc))
				logger.parser('----------------------------------------')
				return False
Beispiel #3
0
			# 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')
			logger.parser(str(exc))
			return False
		except Exception,exc:
			logger.parser('could not parse the message')
			logger.parser(str(exc))
			return False

		logger.parser('')  # new line
		for number in range(len(update.nlris)):
			change = Change(update.nlris[number],update.attributes)
			logger.parser('decoded %s %s %s' % (decoding,change.nlri.action,change.extensive()))
		logger.parser('update json %s' % JSON('3.4.0').update(p,update,'',''))

	return True


# ================================================================= check_update
#

def check_notification (raw):
	notification = Notification.unpack_message(raw[18:],None)
	# XXX: FIXME: should be using logger here
	print notification
	return True
Beispiel #4
0
def check_generation(neighbors):
    option.enabled['parser'] = True

    for name in neighbors.keys():
        neighbor = copy.deepcopy(neighbors[name])
        neighbor['local-as'] = neighbor['peer-as']

        path = {}
        for f in NLRI.known_families():
            if neighbor['capability']['add-path']:
                path[f] = neighbor['capability']['add-path']

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

        routerid_1 = str(neighbor['router-id'])
        routerid_2 = '.'.join(
            str((int(_) + 1) % 250)
            for _ in str(neighbor['router-id']).split('.', -1))

        o1 = Open(Version(4), ASN(neighbor['local-as']), HoldTime(180),
                  RouterID(routerid_1), capa)
        o2 = Open(Version(4), ASN(neighbor['peer-as']), HoldTime(180),
                  RouterID(routerid_2), capa)
        negotiated = Negotiated(neighbor)
        negotiated.sent(o1)
        negotiated.received(o2)
        # grouped = False

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

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

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

            log.debug('parsed route %s' % str1, 'parser')
            log.debug('parsed hex   %s' % od(pack1), 'parser')

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

                pack1s = pack1[19:] if pack1.startswith(b'\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]

                log.debug('recoded route %s' % str2, 'parser')
                log.debug('recoded hex   %s' % od(pack2), 'parser')

                str1 = str1.replace('attribute [ 0x04 0x80 0x00000064 ]',
                                    'med 100')
                str1r = (str1.lower().replace(' med 100', '').replace(
                    ' local-preference 100', '').replace(' origin igp', ''))
                str2r = (str2.lower().replace(' med 100', '').replace(
                    ' local-preference 100', '').replace(' origin igp', ''))
                str2r = str2r.replace(
                    'large-community [ 1:2:3 10:11:12 ]',
                    'attribute [ 0x20 0xc0 0x0000000100000002000000030000000a0000000b0000000c ]',
                )

                if 'next-hop self' in str1r:
                    if ':' in str1r:
                        str1r = str1r.replace('next-hop self', 'next-hop ::1')
                    else:
                        str1r = str1r.replace(
                            'next-hop self',
                            'next-hop %s' % neighbor['local-address'])

                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
                        log.debug(
                            'skipping string check on update with non-transitive attribute(s)',
                            'parser')
                        skip = True
                    else:
                        log.debug('strings are different:', 'parser')
                        log.debug('[%s]' % (str1r), 'parser')
                        log.debug('[%s]' % (str2r), 'parser')
                        return False
                else:
                    log.debug('strings are fine', 'parser')

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

                log.debug('JSON nlri %s' % change1.nlri.json(), 'parser')
                log.debug('JSON attr %s' % change1.attributes.json(), 'parser')

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

    return True
Beispiel #5
0
def check_update(neighbor, raw):
    option.enabled['parser'] = True

    neighbor = neighbor[list(neighbor)[0]]

    path = {}
    for f in NLRI.known_families():
        if neighbor['capability']['add-path']:
            path[f] = neighbor['capability']['add-path']

    capa = Capabilities().new(neighbor, False)
    capa[Capability.CODE.ADD_PATH] = path
    capa[Capability.CODE.MULTIPROTOCOL] = neighbor.families()
    # capa[Capability.CODE.FOUR_BYTES_ASN] = True

    routerid_1 = str(neighbor['router-id'])
    routerid_2 = '.'.join(
        str((int(_) + 1) % 250)
        for _ in str(neighbor['router-id']).split('.', -1))

    o1 = Open(Version(4), ASN(neighbor['local-as']), HoldTime(180),
              RouterID(routerid_1), capa)
    o2 = Open(Version(4), ASN(neighbor['peer-as']), HoldTime(180),
              RouterID(routerid_2), capa)
    negotiated = Negotiated(neighbor)
    negotiated.sent(o1)
    negotiated.received(o2)
    # grouped = False

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

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

            if kind == 2:
                log.debug('the message is an update', 'parser')
                decoding = 'update'
            else:
                log.debug(
                    'the message is not an update (%d) - aborting' % kind,
                    'parser')
                return False
        else:
            log.debug('header missing, assuming this message is ONE update',
                      'parser')
            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 Notify:
            import traceback

            log.error('could not parse the message', 'parser')
            log.error(traceback.format_exc(), 'parser')
            return False
        except Exception:
            import traceback

            log.error('could not parse the message', 'parser')
            log.error(traceback.format_exc(), 'parser')
            return False

        log.debug('', 'parser')  # new line
        for number in range(len(update.nlris)):
            change = Change(update.nlris[number], update.attributes)
            log.info(
                'decoded %s %s %s' %
                (decoding, change.nlri.action, change.extensive()), 'parser')
        log.info(
            'update json %s' % Response.JSON(json_version).update(
                neighbor, 'in', update, None, '', ''), 'parser')

    return True
Beispiel #6
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()
Beispiel #7
0
			# 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

		logger.parser('')  # new line
		for number in range(len(update.nlris)):
			change = Change(update.nlris[number],update.attributes)
			logger.parser('decoded %s %s %s' % (decoding,change.nlri.action,change.extensive()))
		logger.parser('update json %s' % JSON('3.4.0').update(p,update,'',''))

	return True


# ================================================================= check_update
#

def check_notification (raw):
	notification = Notification.unpack_message(raw[18:],None)
	# XXX: FIXME: should be using logger here
	print notification
	return True
Beispiel #8
0
def check_neighbor(neighbor):
    from exabgp.logger import Logger

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

    n = neighbor[neighbor.keys()[0]]

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

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

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

    for nei in neighbor.keys():
        for message in neighbor[nei].rib.outgoing.updates(False):
            pass

        for change1 in neighbor[nei].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('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', '')

                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('----------------------------------------')

            except Notify, e:
                logger.parser('----------------------------------------')
                logger.parser(str(e))
                logger.parser('----------------------------------------')
                return False
Beispiel #9
0
        except KeyboardInterrupt:
            raise
        except Notify, e:
            logger.parser('could not parse the message')
            logger.parser(str(e))
            return False
        except Exception, e:
            logger.parser('could not parse the message')
            logger.parser(str(e))
            return False

        logger.parser('')  # new line
        for number in range(len(update.nlris)):
            change = Change(update.nlris[number], update.attributes)
            logger.parser('decoded %s %s %s' %
                          (decoding, change.nlri.action, change.extensive()))
        logger.parser('update json %s' %
                      JSON('3.4.0').update(p, update, '', ''))

    return True


# ================================================================= check_update
#


def check_notification(raw):
    notification = Notification.unpack_message(raw[18:], None)
    # XXX: FIXME: should be using logger here
    print notification
    return True
Beispiel #10
0
def check_neighbor (neighbors):
	logger = Logger()
	logger._option.parser = True

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

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

		path = {}
		for f in NLRI.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()

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

		o1 = Open(Version(4),ASN(neighbor.local_as),HoldTime(180),RouterID(routerid_1),capa)
		o2 = Open(Version(4),ASN(neighbor.peer_as),HoldTime(180),RouterID(routerid_2),capa)
		negotiated = Negotiated(neighbor)
		negotiated.sent(o1)
		negotiated.received(o2)
		# grouped = False

		for _ 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('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))

				str1 = str1.replace('attribute [ 0x04 0x80 0x00000064 ]','med 100')
				str1r = str1.lower().replace(' med 100','').replace(' local-preference 100','').replace(' origin igp','')
				str2r = str2.lower().replace(' med 100','').replace(' local-preference 100','').replace(' origin igp','')

				if 'next-hop self' in str1r:
					if ':' in str1r:
						str1r = str1r.replace('next-hop self','next-hop ::1')
					else:
						str1r = str1r.replace('next-hop self','next-hop %s' % neighbor.local_address)

				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()
Beispiel #11
0
def check_update (neighbor, raw):
	logger = Logger()
	logger._option.parser = True
	logger.parser('\ndecoding routes in configuration')

	neighbor = neighbor[neighbor.keys()[0]]

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

	capa = Capabilities().new(neighbor,False)
	capa[Capability.CODE.ADD_PATH] = path
	capa[Capability.CODE.MULTIPROTOCOL] = neighbor.families()
	# capa[Capability.CODE.FOUR_BYTES_ASN] = True

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

	o1 = Open(Version(4),ASN(neighbor.local_as),HoldTime(180),RouterID(routerid_1),capa)
	o2 = Open(Version(4),ASN(neighbor.peer_as),HoldTime(180),RouterID(routerid_2),capa)
	negotiated = Negotiated(neighbor)
	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:
			logger.parser('could not parse the message','error')
			logger.parser(traceback.format_exc(),'error')
			return False
		except StandardError:
			logger.parser('could not parse the message','error')
			logger.parser(traceback.format_exc(),'error')
			return False

		logger.parser('')  # new line
		for number in range(len(update.nlris)):
			change = Change(update.nlris[number],update.attributes)
			logger.parser('decoded %s %s %s' % (decoding,change.nlri.action,change.extensive()))
		logger.parser('update json %s' % Response.JSON(json_version).update(neighbor,'in',update,'',''))

	return True
Beispiel #12
0
def check_neighbor(neighbor):
    from exabgp.logger import Logger

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

    n = neighbor[neighbor.keys()[0]]

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

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

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

    for nei in neighbor.keys():
        for message in neighbor[nei].rib.outgoing.updates(False):
            pass

        for change1 in neighbor[nei].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("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", "")

                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("----------------------------------------")

            except Notify, e:
                logger.parser("----------------------------------------")
                logger.parser(str(e))
                logger.parser("----------------------------------------")
                return False
Beispiel #13
0
def check_update(neighbor, raw):
    logger = Logger()
    logger._option.parser = True
    logger.parser('\ndecoding routes in configuration')

    neighbor = neighbor[neighbor.keys()[0]]

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

    capa = Capabilities().new(neighbor, False)
    capa[Capability.CODE.ADD_PATH] = path
    capa[Capability.CODE.MULTIPROTOCOL] = neighbor.families()
    # capa[Capability.CODE.FOUR_BYTES_ASN] = True

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

    o1 = Open(Version(4), ASN(neighbor.local_as), HoldTime(180),
              RouterID(routerid_1), capa)
    o2 = Open(Version(4), ASN(neighbor.peer_as), HoldTime(180),
              RouterID(routerid_2), capa)
    negotiated = Negotiated(neighbor)
    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:
            logger.parser('could not parse the message', 'error')
            logger.parser(traceback.format_exc(), 'error')
            return False
        except StandardError:
            logger.parser('could not parse the message', 'error')
            logger.parser(traceback.format_exc(), 'error')
            return False

        logger.parser('')  # new line
        for number in range(len(update.nlris)):
            change = Change(update.nlris[number], update.attributes)
            logger.parser('decoded %s %s %s' %
                          (decoding, change.nlri.action, change.extensive()))
        logger.parser(
            'update json %s' %
            Response.JSON(json_version).update(neighbor, 'in', update, '', ''))

    return True
Beispiel #14
0
def check_generation(neighbors):
    option.enabled['parser'] = True

    for name in neighbors.keys():
        neighbor = copy.deepcopy(neighbors[name])
        neighbor['local-as'] = neighbor['peer-as']
        negotiated = _negotiated(neighbor)

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

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

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

            log.debug('parsed route %s' % str1, 'parser')
            log.debug('parsed hex   %s' % od(pack1), 'parser')

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

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

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

                log.debug('recoded route %s' % str2, 'parser')
                log.debug('recoded hex   %s' % od(pack2), 'parser')

                str1 = str1.replace('attribute [ 0x04 0x80 0x00000064 ]', 'med 100')
                str1r = (
                    str1.lower().replace(' med 100', '').replace(' local-preference 100', '').replace(' origin igp', '')
                )
                str2r = (
                    str2.lower().replace(' med 100', '').replace(' local-preference 100', '').replace(' origin igp', '')
                )
                str2r = str2r.replace(
                    'large-community [ 1:2:3 10:11:12 ]',
                    'attribute [ 0x20 0xc0 0x0000000100000002000000030000000a0000000b0000000c ]',
                )

                if 'next-hop self' in str1r:
                    if ':' in str1r:
                        str1r = str1r.replace('next-hop self', 'next-hop ::1')
                    else:
                        str1r = str1r.replace('next-hop self', 'next-hop %s' % neighbor['local-address'])

                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
                        log.debug('skipping string check on update with non-transitive attribute(s)', 'parser')
                        skip = True
                    else:
                        log.debug('strings are different:', 'parser')
                        log.debug('[%s]' % (str1r), 'parser')
                        log.debug('[%s]' % (str2r), 'parser')
                        return False
                else:
                    log.debug('strings are fine', 'parser')

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

                log.debug('JSON nlri %s' % change1.nlri.json(), 'parser')
                log.debug('JSON attr %s' % change1.attributes.json(), 'parser')

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

    return True