def read_message (self): # This will always be defined by the loop but scope leaking upset scrutinizer/pylint msg_id = None packets = self.neighbor.api['receive-packets'] consolidate = self.neighbor.api['receive-consolidate'] parsed = self.neighbor.api['receive-parsed'] body,header = '','' # just because pylint/pylama are getting more clever for length,msg_id,header,body,notify in self.connection.reader(): # internal issue if notify: if self.neighbor.api.get('send-%s' % Message.CODE.NOTIFICATION.SHORT,False): if consolidate: self.peer.reactor.processes.notification(self.peer.neighbor,'send',notify.code,notify.subcode,str(notify),header,body) elif parsed: self.peer.reactor.processes.notification(self.peer.neighbor,'send',notify.code,notify.subcode,str(notify),'','') elif packets: self.peer.reactor.processes.packets(self.peer.neighbor,'send',msg_id,header,body) # XXX: is notify not already Notify class ? raise Notify(notify.code,notify.subcode,str(notify)) if not length: yield _NOP continue self.logger.message(self.me('<< %s' % Message.CODE.name(msg_id))) for_api = self.neighbor.api.get('receive-%s' % Message.CODE.short(msg_id),False) if for_api and packets and not consolidate: self.peer.reactor.processes.packets(self.peer.neighbor,'receive',msg_id,header,body) if msg_id == Message.CODE.UPDATE: if not (for_api or self.log_routes) and not (parsed or consolidate): yield _UPDATE return try: message = Message.unpack(msg_id,body,self.negotiated) except (KeyboardInterrupt,SystemExit,Notify): raise except Exception,exc: self.logger.message(self.me('Could not decode message "%d"' % msg_id)) self.logger.message(self.me('%s' % str(exc))) self.logger.message(traceback.format_exc()) raise Notify(1,0,'can not decode update message of type "%d"' % msg_id) # raise Notify(5,0,'unknown message received') if for_api: if consolidate: self.peer.reactor.processes.message(msg_id,self.neighbor,'receive',message,header,body) elif parsed: self.peer.reactor.processes.message(msg_id,self.neighbor,'receive',message,'','') if message.TYPE == Notification.TYPE: raise message yield message
def read_message (self): # This will always be defined by the loop but scope leaking upset scrutinizer/pylint msg_id = None for length,msg_id,header,body,notify in self.connection.reader(): if notify: if self.neighbor.api['receive-packets']: self.peer.reactor.processes.receive(self.peer,msg_id,header,body) if self.neighbor.api[Message.CODE.NOTIFICATION]: self.peer.reactor.processes.notification(self.peer,notify.code,notify.subcode,str(notify)) # XXX: is notify not already Notify class ? raise Notify(notify.code,notify.subcode,str(notify)) if not length: yield _NOP if self.neighbor.api['receive-packets'] and not self.neighbor.api['consolidate']: self.peer.reactor.processes.receive(self.peer,msg_id,header,body) if msg_id == Message.CODE.UPDATE and not self.neighbor.api['receive-parsed'] and not self.log_routes: yield _UPDATE return self.logger.message(self.me('<< %s' % Message.CODE.name(msg_id))) try: message = Message.unpack(msg_id,body,self.negotiated) except (KeyboardInterrupt,SystemExit,Notify): raise except Exception,exc: self.logger.message(self.me('Could not decode message "%d"' % msg_id)) self.logger.message(self.me('%s' % str(exc))) # XXX: TODO: add backtrace here raise Notify(1,0,'can not decode update message of type "%d"' % msg_id)
def read_message(self): # This will always be defined by the loop but scope leaking upset scrutinizer/pylint msg_id = None packets = self.neighbor.api['receive-packets'] consolidate = self.neighbor.api['receive-consolidate'] parsed = self.neighbor.api['receive-parsed'] body, header = '', '' # just because pylint/pylama are getting more clever for length, msg_id, header, body, notify in self.connection.reader(): if notify: if self.neighbor.api['receive-%s' % Message.CODE.NOTIFICATION.SHORT]: if packets and not consolidate: self.peer.reactor.processes.packets( self.peer.neighbor, 'receive', msg_id, header, body) if not packets or consolidate: header = '' body = '' self.peer.reactor.processes.notification( self.peer.neighbor, 'receive', notify.code, notify.subcode, str(notify), header, body) # XXX: is notify not already Notify class ? raise Notify(notify.code, notify.subcode, str(notify)) if not length: yield _NOP if packets and not consolidate: self.peer.reactor.processes.packets(self.peer.neighbor, 'receive', msg_id, header, body) if msg_id == Message.CODE.UPDATE: if not parsed and not self.log_routes: yield _UPDATE return self.logger.message(self.me('<< %s' % Message.CODE.name(msg_id))) try: message = Message.unpack(msg_id, body, self.negotiated) except (KeyboardInterrupt, SystemExit, Notify): raise except Exception, exc: self.logger.message( self.me('Could not decode message "%d"' % msg_id)) self.logger.message(self.me('%s' % str(exc))) self.logger.message(traceback.format_exc()) raise Notify(1, 0, 'can not decode update message of type "%d"' % msg_id)
def read_message (self): # This will always be defined by the loop but scope leaking upset scrutinizer/pylint msg_id = None packets = self.neighbor.api['receive-packets'] consolidate = self.neighbor.api['receive-consolidate'] parsed = self.neighbor.api['receive-parsed'] body,header = '','' # just because pylint/pylama are getting more clever for length,msg_id,header,body,notify in self.connection.reader(): if notify: if self.neighbor.api['receive-%s' % Message.CODE.NOTIFICATION.SHORT]: if packets and not consolidate: self.peer.reactor.processes.packets(self.peer.neighbor,'receive',msg_id,header,body) if not packets or consolidate: header = '' body = '' self.peer.reactor.processes.notification(self.peer.neighbor,'receive',notify.code,notify.subcode,str(notify),header,body) # XXX: is notify not already Notify class ? raise Notify(notify.code,notify.subcode,str(notify)) if not length: yield _NOP if packets and not consolidate: self.peer.reactor.processes.packets(self.peer.neighbor,'receive',msg_id,header,body) if msg_id == Message.CODE.UPDATE: if not parsed and not self.log_routes: yield _UPDATE return self.logger.message(self.me('<< %s' % Message.CODE.name(msg_id))) try: message = Message.unpack(msg_id,body,self.negotiated) except (KeyboardInterrupt,SystemExit,Notify): raise except Exception,exc: self.logger.message(self.me('Could not decode message "%d"' % msg_id)) self.logger.message(self.me('%s' % str(exc))) self.logger.message(traceback.format_exc()) raise Notify(1,0,'can not decode update message of type "%d"' % msg_id)
def test_1_open (self): check_capa = { 1: [(AFI.ipv4, SAFI.unicast), (AFI.ipv6, SAFI.unicast)], 2: RouteRefresh(), 65: 65534, 128: RouteRefresh(), } message_id = 1 negotiated = {'invalid':'test'} o = Message.unpack(message_id,data_from_body(open_body),negotiated) self.assertEqual(o.version,4) self.assertEqual(o.asn,65534) self.assertEqual(o.router_id,RouterID('0.0.0.0')) self.assertEqual(o.hold_time,180) for k,v in o.capabilities.items(): self.assertEqual(v,check_capa[k])
def test_1_open(self): check_capa = { 1: [(AFI.ipv4, SAFI.unicast), (AFI.ipv6, SAFI.unicast)], 2: RouteRefresh(), 65: 65534, 128: RouteRefresh(), } message_id = 1 negotiated = {'invalid': 'test'} o = Message.unpack(message_id, data_from_body(open_body), negotiated) self.assertEqual(o.version, 4) self.assertEqual(o.asn, 65534) self.assertEqual(o.router_id, RouterID('0.0.0.0')) self.assertEqual(o.hold_time, 180) for k, v in o.capabilities.items(): self.assertEqual(v, check_capa[k])
def read_message(self): # This will always be defined by the loop but scope leaking upset scrutinizer/pylint msg_id = None for length, msg_id, header, body, notify in self.connection.reader(): if notify: if self.neighbor.api['receive-packets']: self.peer.reactor.processes.receive( self.peer, msg_id, header, body) if self.neighbor.api[Message.CODE.NOTIFICATION]: self.peer.reactor.processes.notification( self.peer, notify.code, notify.subcode, str(notify)) # XXX: is notify not already Notify class ? raise Notify(notify.code, notify.subcode, str(notify)) if not length: yield _NOP if self.neighbor.api[ 'receive-packets'] and not self.neighbor.api['consolidate']: self.peer.reactor.processes.receive(self.peer, msg_id, header, body) if msg_id == Message.CODE.UPDATE and not self.neighbor.api[ 'receive-parsed'] and not self.log_routes: yield _UPDATE return self.logger.message(self.me('<< %s' % Message.CODE.name(msg_id))) try: message = Message.unpack(msg_id, body, self.negotiated) except (KeyboardInterrupt, SystemExit, Notify): raise except Exception, exc: self.logger.message( self.me('Could not decode message "%d"' % msg_id)) self.logger.message(self.me('%s' % str(exc))) # XXX: TODO: add backtrace here raise Notify(1, 0, 'can not decode update message of type "%d"' % msg_id)
def _from_json(self, direction, json_string): try: parsed = json.loads(json_string) except ValueError: print('invalid JSON message', file=sys.stderr) sys.exit(1) if parsed.get('exabgp', '0.0.0') != json_version: print('invalid json version', json_string, file=sys.stderr) sys.exit(1) content = parsed.get('type', '') if not content: print('invalid json content', json_string, file=sys.stderr) sys.exit(1) neighbor = _FakeNeighbor( parsed['neighbor']['address']['local'], parsed['neighbor']['address']['peer'], parsed['neighbor']['asn']['local'], parsed['neighbor']['asn']['peer'], ) if content == 'state': self._state() return json_string direction = parsed['neighbor']['direction'] category = parsed['neighbor']['message']['category'] header = parsed['neighbor']['message']['header'] body = parsed['neighbor']['message']['body'] data = b''.join(bytes([int(body[_ : _ + 2], 16)]) for _ in range(0, len(body), 2)) if content == 'open': message = Open.unpack_message(data) self._open(direction, message) return self.encoder.open(neighbor, direction, message, None, header, body) if content == 'keepalive': return self.encoder.keepalive(neighbor, direction, None, header, body) if content == 'notification': # XXX: Use the code of the Notifcation class here .. message = Notification.unpack_message(data) if (message.code, message.subcode) != (6, 2): message.data = data if not len([_ for _ in data if _ not in string.printable]) else hexstring(data) return self.encoder.notification(neighbor, direction, message, None, header, body) if len(data) == 0: # shutdown without shutdown communication (the old fashioned way) message.data = '' return self.encoder.notification(neighbor, direction, message, None, header, body) # draft-ietf-idr-shutdown or the peer was using 6,2 with data shutdown_length = data[0] data = data[1:] if shutdown_length == 0: message.data = "empty Shutdown Communication." # move offset past length field return self.encoder.notification(neighbor, direction, message, None, header, body) if len(data) < shutdown_length: message.data = "invalid Shutdown Communication (buffer underrun) length : %i [%s]" % ( shutdown_length, hexstring(data), ) return self.encoder.notification(neighbor, direction, message, None, header, body) if shutdown_length > 128: message.data = "invalid Shutdown Communication (too large) length : %i [%s]" % ( shutdown_length, hexstring(data), ) return self.encoder.notification(neighbor, direction, message, None, header, body) try: message.data = 'Shutdown Communication: "%s"' % data[:shutdown_length].decode('utf-8').replace( '\r', ' ' ).replace('\n', ' ') except UnicodeDecodeError: message.data = "invalid Shutdown Communication (invalid UTF-8) length : %i [%s]" % ( shutdown_length, hexstring(data), ) return self.encoder.notification(neighbor, direction, message, None, header, body) trailer = data[shutdown_length:] if trailer: message.data += ", trailing data: " + hexstring(trailer) return self.encoder.notification(neighbor, direction, message, None, header, body) if not self.negotiated: print('invalid message sequence, open not exchange not complete', json_string, file=sys.stderr) sys.exit(1) message = Message.unpack(category, data, direction, self.negotiated) if content == 'update': return self.encoder.update(neighbor, direction, message, None, header, body) if content == 'eor': # XXX: Should not be required return self.encoder.update(neighbor, direction, message, None, header, body) if content == 'refresh': return self.json.refresh(neighbor, direction, message, None, header, body) if content == 'operational': return self.json.refresh(neighbor, direction, message, None, header, body) raise RuntimeError('the programer is a monkey and forgot a JSON message type')
65: 65534L, 128: RouteRefresh(), } message_id = 1 body = ''.join([ chr(c) for c in [ 0x4, 0xff, 0xfe, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x20, 0x2, 0x6, 0x1, 0x4, 0x0, 0x1, 0x0, 0x1, 0x2, 0x6, 0x1, 0x4, 0x0, 0x2, 0x0, 0x1, 0x2, 0x2, 0x80, 0x0, 0x2, 0x2, 0x2, 0x0, 0x2, 0x6, 0x41, 0x4, 0x0, 0x0, 0xff, 0xfe ] ]) negotiated = {'invalid': 'test'} o = Message.unpack(message_id, body, negotiated) self.assertEqual(o.version, 4) self.assertEqual(o.asn, 65534) self.assertEqual(o.router_id, RouterID('0.0.0.0')) self.assertEqual(o.hold_time, 180) for k, v in o.capabilities.items(): self.assertEqual(v, check_capa[k]) 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)
def _from_json (self, string): try: parsed = json.loads(string) except ValueError: print >> sys.stderr, 'invalid JSON message' sys.exit(1) if parsed.get('exabgp','0.0.0') != json_version: print >> sys.stderr, 'invalid json version', string sys.exit(1) content = parsed.get('type','') if not content: print >> sys.stderr, 'invalid json content', string sys.exit(1) neighbor = _FakeNeighbor( parsed['neighbor']['address']['local'], parsed['neighbor']['address']['peer'], parsed['neighbor']['asn']['local'], parsed['neighbor']['asn']['peer'], ) if content == 'state': self._state() return string direction = parsed['neighbor']['direction'] category = parsed['neighbor']['message']['category'] header = parsed['neighbor']['message']['header'] body = parsed['neighbor']['message']['body'] raw = ''.join(chr(int(body[_:_+2],16)) for _ in range(0,len(body),2)) if content == 'open': message = Open.unpack_message(raw) self._open(direction,message) return self.encoder.open(neighbor,direction,message,header,body) if content == 'keapalive': return self.encoder.keepalive(neighbor,direction,header,body) if content == 'notification': return self.encoder.notification(neighbor,direction,ord(message[0]),ord(message[1]),message[2:],header,body) if not self.negotiated: print >> sys.stderr, 'invalid message sequence, open not exchange not complete', string sys.exit(1) message = Message.unpack(category,raw,self.negotiated) if content == 'update': return self.encoder.update(neighbor, direction, message, header,body) if content == 'eor': # XXX: Should not be required return self.encoder.update(neighbor, direction, message, header,body) if content == 'refresh': return self.json.refresh(neighbor, direction, message, header,body) if content == 'operational': return self.json.refresh(neighbor, direction, message, header,body) raise RuntimeError('the programer is a monkey and forgot a JSON message type')
def read_message(self): # This will always be defined by the loop but scope leaking upset scrutinizer/pylint msg_id = None packets = self.neighbor.api['receive-packets'] consolidate = self.neighbor.api['receive-consolidate'] parsed = self.neighbor.api['receive-parsed'] body, header = b'', b'' # just because pylint/pylama are getting more clever for length, msg_id, header, body, notify in self.connection.reader(): # internal issue if notify: code = 'receive-%s' % Message.CODE.NOTIFICATION.SHORT if self.neighbor.api.get(code, False): if consolidate: self.peer.reactor.processes.notification( self.peer.neighbor, 'receive', notify.code, notify.subcode, str(notify), None, header, body) elif parsed: self.peer.reactor.processes.notification( self.peer.neighbor, 'receive', notify.code, notify.subcode, str(notify), None, b'', b'') elif packets: self.peer.reactor.processes.packets( self.peer.neighbor, 'receive', msg_id, None, header, body) # XXX: is notify not already Notify class ? raise Notify(notify.code, notify.subcode, str(notify)) if not length: yield _NOP continue log.debug('<< message of type %s' % Message.CODE.name(msg_id), self.connection.session()) code = 'receive-%s' % Message.CODE.short(msg_id) self.peer.stats[code] = self.peer.stats.get(code, 0) + 1 for_api = self.neighbor.api.get(code, False) if for_api and packets and not consolidate: negotiated = self.negotiated if self.neighbor.api.get( 'negotiated', False) else None self.peer.reactor.processes.packets(self.peer.neighbor, 'receive', msg_id, negotiated, header, body) if msg_id == Message.CODE.UPDATE: if not self.neighbor['adj-rib-in'] and not ( for_api or self.log_routes) and not (parsed or consolidate): yield _UPDATE return try: message = Message.unpack(msg_id, body, Direction.IN, self.negotiated) except (KeyboardInterrupt, SystemExit, Notify): raise except Exception as exc: log.debug('could not decode message "%d"' % msg_id, self.connection.session()) log.debug('%s' % str(exc), self.connection.session()) log.debug(traceback.format_exc(), self.connection.session()) raise Notify( 1, 0, 'can not decode update message of type "%d"' % msg_id) # raise Notify(5,0,'unknown message received') if message.TYPE == Update.TYPE: if Attribute.CODE.INTERNAL_TREAT_AS_WITHDRAW in message.attributes: for nlri in message.nlris: nlri.action = IN.WITHDRAWN if for_api: negotiated = self.negotiated if self.neighbor.api.get( 'negotiated', False) else None if consolidate: self.peer.reactor.processes.message( msg_id, self.neighbor, 'receive', message, negotiated, header, body) elif parsed: self.peer.reactor.processes.message( msg_id, self.neighbor, 'receive', message, negotiated, b'', b'') if message.TYPE == Notification.TYPE: raise message if message.TYPE == Update.TYPE and Attribute.CODE.INTERNAL_DISCARD in message.attributes: yield _NOP else: yield message
def _from_json(self, string): try: parsed = json.loads(string) except ValueError: print >> sys.stderr, 'invalid JSON message' sys.exit(1) if parsed.get('exabgp', '0.0.0') != json_version: print >> sys.stderr, 'invalid json version', string sys.exit(1) content = parsed.get('type', '') if not content: print >> sys.stderr, 'invalid json content', string sys.exit(1) neighbor = _FakeNeighbor( parsed['neighbor']['address']['local'], parsed['neighbor']['address']['peer'], parsed['neighbor']['asn']['local'], parsed['neighbor']['asn']['peer'], ) if content == 'state': self._state() return string direction = parsed['neighbor']['direction'] category = parsed['neighbor']['message']['category'] header = parsed['neighbor']['message']['header'] body = parsed['neighbor']['message']['body'] raw = ''.join( chr(int(body[_:_ + 2], 16)) for _ in range(0, len(body), 2)) if content == 'open': message = Open.unpack_message(raw) self._open(direction, message) return self.encoder.open(neighbor, direction, message, header, body) if content == 'keapalive': return self.encoder.keepalive(neighbor, direction, header, body) if content == 'notification': message = Notification.unpack_message(raw) return self.encoder.notification(neighbor, direction, message, header, body) if not self.negotiated: print >> sys.stderr, 'invalid message sequence, open not exchange not complete', string sys.exit(1) message = Message.unpack(category, raw, self.negotiated) if content == 'update': return self.encoder.update(neighbor, direction, message, header, body) if content == 'eor': # XXX: Should not be required return self.encoder.update(neighbor, direction, message, header, body) if content == 'refresh': return self.json.refresh(neighbor, direction, message, header, body) if content == 'operational': return self.json.refresh(neighbor, direction, message, header, body) raise RuntimeError( 'the programer is a monkey and forgot a JSON message type')
def read_message(self): # This will always be defined by the loop but scope leaking upset scrutinizer/pylint msg_id = None packets = self.neighbor.api['receive-packets'] consolidate = self.neighbor.api['receive-consolidate'] parsed = self.neighbor.api['receive-parsed'] body, header = '', '' # just because pylint/pylama are getting more clever for length, msg_id, header, body, notify in self.connection.reader(): # internal issue if notify: if self.neighbor.api.get( 'send-%s' % Message.CODE.NOTIFICATION.SHORT, False): if consolidate: self.peer.reactor.processes.notification( self.peer.neighbor, 'send', notify.code, notify.subcode, str(notify), header, body) elif parsed: self.peer.reactor.processes.notification( self.peer.neighbor, 'send', notify.code, notify.subcode, str(notify), '', '') elif packets: self.peer.reactor.processes.packets( self.peer.neighbor, 'send', msg_id, header, body) # XXX: is notify not already Notify class ? raise Notify(notify.code, notify.subcode, str(notify)) if not length: yield _NOP continue self.logger.message(self.me('<< %s' % Message.CODE.name(msg_id))) for_api = self.neighbor.api.get( 'receive-%s' % Message.CODE.short(msg_id), False) if for_api and packets and not consolidate: self.peer.reactor.processes.packets(self.peer.neighbor, 'receive', msg_id, header, body) if msg_id == Message.CODE.UPDATE: if not (for_api or self.log_routes) and not (parsed or consolidate): yield _UPDATE return try: message = Message.unpack(msg_id, body, self.negotiated) except (KeyboardInterrupt, SystemExit, Notify): raise except Exception, exc: self.logger.message( self.me('Could not decode message "%d"' % msg_id)) self.logger.message(self.me('%s' % str(exc))) self.logger.message(traceback.format_exc()) raise Notify( 1, 0, 'can not decode update message of type "%d"' % msg_id) # raise Notify(5,0,'unknown message received') if for_api: if consolidate: self.peer.reactor.processes.message( msg_id, self.neighbor, 'receive', message, header, body) elif parsed: self.peer.reactor.processes.message( msg_id, self.neighbor, 'receive', message, '', '') if message.TYPE == Notification.TYPE: raise message yield message
def read_message (self): # This will always be defined by the loop but scope leaking upset scrutinizer/pylint msg_id = None packets = self.neighbor.api['receive-packets'] consolidate = self.neighbor.api['receive-consolidate'] parsed = self.neighbor.api['receive-parsed'] body,header = b'',b'' # just because pylint/pylama are getting more clever for length,msg_id,header,body,notify in self.connection.reader(): # internal issue if notify: code = 'receive-%s' % Message.CODE.NOTIFICATION.SHORT if self.neighbor.api.get(code,False): if consolidate: self.peer.reactor.processes.notification(self.peer.neighbor,'receive',notify.code,notify.subcode,str(notify),None,header,body) elif parsed: self.peer.reactor.processes.notification(self.peer.neighbor,'receive',notify.code,notify.subcode,str(notify),None,b'',b'') elif packets: self.peer.reactor.processes.packets(self.peer.neighbor,'receive',msg_id,None,header,body) # XXX: is notify not already Notify class ? raise Notify(notify.code,notify.subcode,str(notify)) if not length: yield _NOP continue self.logger.debug('<< message of type %s' % Message.CODE.name(msg_id),self.connection.session()) code = 'receive-%s' % Message.CODE.short(msg_id) self.peer.stats[code] = self.peer.stats.get(code,0) + 1 for_api = self.neighbor.api.get(code,False) if for_api and packets and not consolidate: negotiated = self.negotiated if self.neighbor.api.get('negotiated',False) else None self.peer.reactor.processes.packets(self.peer.neighbor,'receive',msg_id,negotiated,header,body) if msg_id == Message.CODE.UPDATE: if not self.neighbor.adj_rib_in and not (for_api or self.log_routes) and not (parsed or consolidate): yield _UPDATE return try: message = Message.unpack(msg_id,body,self.negotiated) except (KeyboardInterrupt,SystemExit,Notify): raise except Exception as exc: self.logger.debug('could not decode message "%d"' % msg_id,self.connection.session()) self.logger.debug('%s' % str(exc),self.connection.session()) self.logger.debug(traceback.format_exc(),self.connection.session()) raise Notify(1,0,'can not decode update message of type "%d"' % msg_id) # raise Notify(5,0,'unknown message received') if message.TYPE == Update.TYPE: if Attribute.CODE.INTERNAL_TREAT_AS_WITHDRAW in message.attributes: for nlri in message.nlris: nlri.action = IN.WITHDRAWN if for_api: negotiated = self.negotiated if self.neighbor.api.get('negotiated',False) else None if consolidate: self.peer.reactor.processes.message(msg_id,self.neighbor,'receive',message,negotiated,header,body) elif parsed: self.peer.reactor.processes.message(msg_id,self.neighbor,'receive',message,negotiated,b'',b'') if message.TYPE == Notification.TYPE: raise message if message.TYPE == Update.TYPE and Attribute.CODE.INTERNAL_DISCARD in message.attributes: yield _NOP else: yield message
0x2, 0x0, 0x2, 0x6, 0x41, 0x4, 0x0, 0x0, 0xFF, 0xFE, ] ] ) negotiated = {"invalid": "test"} o = Message.unpack(message_id, body, negotiated) self.assertEqual(o.version, 4) self.assertEqual(o.asn, 65534) self.assertEqual(o.router_id, RouterID("0.0.0.0")) self.assertEqual(o.hold_time, 180) for k, v in o.capabilities.items(): self.assertEqual(v, check_capa[k]) 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)
def _from_json (self, json_string): try: parsed = json.loads(json_string) except ValueError: print('invalid JSON message', file=sys.stderr) sys.exit(1) if parsed.get('exabgp','0.0.0') != json_version: print('invalid json version', json_string, file=sys.stderr) sys.exit(1) content = parsed.get('type','') if not content: print('invalid json content', json_string, file=sys.stderr) sys.exit(1) neighbor = _FakeNeighbor( parsed['neighbor']['address']['local'], parsed['neighbor']['address']['peer'], parsed['neighbor']['asn']['local'], parsed['neighbor']['asn']['peer'], ) if content == 'state': self._state() return json_string direction = parsed['neighbor']['direction'] category = parsed['neighbor']['message']['category'] header = parsed['neighbor']['message']['header'] body = parsed['neighbor']['message']['body'] data = concat_bytes_i(character(int(body[_:_+2],16)) for _ in range(0,len(body),2)) if content == 'open': message = Open.unpack_message(data) self._open(direction,message) return self.encoder.open(neighbor,direction,message,None,header,body) if content == 'keepalive': return self.encoder.keepalive(neighbor,direction,None,header,body) if content == 'notification': # XXX: Use the code of the Notifcation class here .. message = Notification.unpack_message(data) if (message.code, message.subcode) != (6, 2): message.data = data if not len([_ for _ in data if _ not in string.printable]) else hexstring(data) return self.encoder.notification(neighbor,direction,message,None,header,body) if len(data) == 0: # shutdown without shutdown communication (the old fashioned way) message.data = '' return self.encoder.notification(neighbor,direction,message,None,header,body) # draft-ietf-idr-shutdown or the peer was using 6,2 with data shutdown_length = ordinal(data[0]) data = data[1:] if shutdown_length == 0: message.data = "empty Shutdown Communication." # move offset past length field return self.encoder.notification(neighbor,direction,message,None,header,body) if len(data) < shutdown_length: message.data = "invalid Shutdown Communication (buffer underrun) length : %i [%s]" % (shutdown_length, hexstring(data)) return self.encoder.notification(neighbor,direction,message,None,header,body) if shutdown_length > 128: message.data = "invalid Shutdown Communication (too large) length : %i [%s]" % (shutdown_length, hexstring(data)) return self.encoder.notification(neighbor,direction,message,None,header,body) try: message.data = 'Shutdown Communication: "%s"' % \ data[:shutdown_length].decode('utf-8').replace('\r',' ').replace('\n',' ') except UnicodeDecodeError: message.data = "invalid Shutdown Communication (invalid UTF-8) length : %i [%s]" % (shutdown_length, hexstring(data)) return self.encoder.notification(neighbor,direction,message,None,header,body) trailer = data[shutdown_length:] if trailer: message.data += ", trailing data: " + hexstring(trailer) return self.encoder.notification(neighbor,direction,message,None,header,body) if not self.negotiated: print('invalid message sequence, open not exchange not complete', json_string, file=sys.stderr) sys.exit(1) message = Message.unpack(category,data,self.negotiated) if content == 'update': return self.encoder.update(neighbor, direction, message, None, header,body) if content == 'eor': # XXX: Should not be required return self.encoder.update(neighbor, direction, message, None, header,body) if content == 'refresh': return self.json.refresh(neighbor, direction, message, None, header,body) if content == 'operational': return self.json.refresh(neighbor, direction, message, None, header,body) raise RuntimeError('the programer is a monkey and forgot a JSON message type')