def _negotiated(neighbor): 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 return negotiated
def test_2_open(self): capabilities = Capabilities() o = Open(Version(4), ASN(65500), HoldTime(180), RouterID('127.0.0.1'), capabilities) 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, {})
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
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
def check_neighbor(neighbors): 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 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() o1 = Open(Version(4), ASN(neighbor.local_as), HoldTime(180), RouterID(neighbor.local_address.top()), capa) o2 = Open(Version(4), ASN(neighbor.peer_as), HoldTime(180), RouterID(neighbor.peer_address.top()), 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 127.0.0.1') 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()
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