def read_message (self): for length,msg,header,body,notify in self.connection.reader(): if notify: if self.neighbor.api['receive-packets']: self.peer.reactor.processes.receive(self.peer,msg,header,body) if self.neighbor.api[Message.ID.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,header,body) if msg == Message.ID.UPDATE and not self.neighbor.api['receive-parsed'] and not self.log_routes: yield _UPDATE return self.logger.message(self.me('<< %s' % Message.ID.name(msg))) try: message = Message.unpack_message(msg,body,self.negotiated) except (KeyboardInterrupt,SystemExit,Notify): raise except Exception,e: self.logger.message(self.me('Could not decode message %s' % Capability.hex(msg))) self.logger.message(self.me('%s' % str(e))) raise Notify(2,0,'can not decode update message %s' % Capability.hex(msg))
def read_message(self): for length, msg, header, body, notify in self.connection.reader(): if notify: if self.neighbor.api['receive-packets']: self.peer.reactor.processes.receive( self.peer, msg, header, body) if self.neighbor.api[Message.ID.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, header, body) if msg == Message.ID.UPDATE and not self.neighbor.api[ 'receive-parsed'] and not self.log_routes: yield _UPDATE return self.logger.message(self.me('<< %s' % Message.ID.name(msg))) try: message = Message.unpack_message(msg, body, self.negotiated) except (KeyboardInterrupt, SystemExit, Notify): raise except Exception, e: self.logger.message( self.me('Could not decode message %s' % Capability.hex(msg))) self.logger.message(self.me('%s' % str(e))) raise Notify( 2, 0, 'can not decode update message %s' % Capability.hex(msg))
def family(self, tokeniser): data = self.get_section(SectionFamily.name, tokeniser) if data: self.content[Capability.CODE( Capability.CODE.MULTIPROTOCOL)] = MultiProtocol( (afi, safi) for afi in sorted(data) for safi in sorted(data[afi])) else: return False
def enter(self, tokeniser): Section.enter(self, tokeniser) self.content[Capability.CODE(Capability.CODE.FOUR_BYTES_ASN)] = True self.content[Capability.CODE(Capability.CODE.AIGP)] = False self.content[Capability.CODE(Capability.CODE.ADD_PATH)] = 0 self.content[Capability.CODE(Capability.CODE.OPERATIONAL)] = False self.content[Capability.CODE(Capability.CODE.ROUTE_REFRESH)] = False self.content[Capability.CODE(Capability.CODE.MULTISESSION)] = False self.content[Capability.CODE(Capability.CODE.GRACEFUL_RESTART)] = 0
def addpath(self, tokeniser): self._check_duplicate(tokeniser, RaisedCapability) valid_options = ('receive', 'send', 'send/receive', 'disable', 'disabled') ap = tokeniser() if ap not in valid_options: raise RaisedCapability( tokeniser, "%s is not a invalid add-path paramerter, options are %s" % (ap, ', '.join(valid_options))) self.content[Capability.ID(Capability.ID.ADD_PATH)] = 0 if ap.endswith('receive'): self.content[Capability.ID.ADD_PATH] += 1 if ap.startswith('send'): self.content[Capability.ID.ADD_PATH] += 2
def graceful(self, tokeniser): self._check_duplicate(tokeniser, RaisedCapability) token = tokeniser() if not token.isdigit(): raise RaisedCapability( tokeniser, "%s is not a valid option for graceful-restart, it must be a positive number smaller than 2^16" % token) duration = int(token) if duration < 0: raise RaisedCapability( tokeniser, "%s is not a valid option for graceful-restart, it must be a positive number smaller than 2^16" % token) if duration > pow(2, 16): raise RaisedCapability( tokeniser, "%s is not a valid option for graceful-restart, it must be a positive number smaller than 2^16" % token) self.content[Capability.ID(Capability.ID.GRACEFUL_RESTART)] = duration
def aigp(self, tokeniser): self._check_duplicate(tokeniser, RaisedCapability) self.content[Capability.CODE(Capability.CODE.AIGP)] = boolean( tokeniser, False)
def asn4(self, tokeniser): self._check_duplicate(tokeniser, RaisedCapability) self.content[Capability.CODE( Capability.CODE.FOUR_BYTES_ASN)] = boolean(tokeniser, True)
def exit(self, tokeniser): if Capability.CODE(Capability.CODE.MULTIPROTOCOL) not in self.content: self.content[Capability.CODE( Capability.CODE.MULTIPROTOCOL)] = MultiProtocol( NLRI.known_families())
def multisession(self, tokeniser): self._check_duplicate(tokeniser, RaisedCapability) self.content[Capability.CODE( Capability.CODE.MULTISESSION_CISCO)] = boolean(tokeniser, False)
def refresh(self, tokeniser): self._check_duplicate(tokeniser, RaisedCapability) self.content[Capability.CODE(Capability.CODE.ROUTE_REFRESH)] = boolean( tokeniser, False)
def operational(self, tokeniser): self._check_duplicate(tokeniser, RaisedCapability) self.content[Capability.CODE(Capability.CODE.OPERATIONAL)] = boolean( tokeniser, False)
# ============================================================ UnknownCapability # class UnknownCapability (Capability): def set (self,value,raw=''): self.value = value self.raw = raw def __str__ (self): if self.value in Capability.ID.reserved: return 'Reserved %s' % str(self.value) if self.value in Capability.ID.unassigned: return 'Unassigned %s' % str(self.value) return 'Unknown %s' % str(self.value) def json (self): if self.value in Capability.ID.reserved: iana = 'reserved' elif self.value in Capability.ID.unassigned: iana = 'unassigned' else: iana = 'unknown' return '{ "name": "unknown", "iana": "%s", "value": %d, "raw": "%s" }' % (iana,self.value,self.raw) def extract (self): return [] @staticmethod def unpack (capability,instance,data): return instance.set(capability,data) Capability.fallback_capability(UnknownCapability)
def set(self, value, raw=''): self.value = value self.raw = raw def __str__(self): if self.value in Capability.ID.reserved: return 'Reserved %s' % str(self.value) if self.value in Capability.ID.unassigned: return 'Unassigned %s' % str(self.value) return 'Unknown %s' % str(self.value) def json(self): if self.value in Capability.ID.reserved: iana = 'reserved' elif self.value in Capability.ID.unassigned: iana = 'unassigned' else: iana = 'unknown' return '{ "name": "unknown", "iana": "%s", "value": %d, "raw": "%s" }' % ( iana, self.value, self.raw) def extract(self): return [] @staticmethod def unpack(capability, instance, data): return instance.set(capability, data) Capability.fallback_capability(UnknownCapability)