def unpack(afi, safi, data): len_in_bits = ord(data[0]) data = data[1:] if (len_in_bits == 0): return RouteTargetConstraint(afi, safi, ASN(0), None) if (len_in_bits < 4): raise Exception("RTC route too short to be decoded") asn = ASN(unpack('!L', data[0:4])[0]) data = data[4:] rt = RouteTarget.unpackFrom(data) return RouteTargetConstraint(afi, safi, asn, rt)
class Open (Message): TYPE = chr(0x01) def __init__ (self,version,asn,router_id,capabilities,hold_time): self.version = Version(version) self.asn = ASN(asn) self.hold_time = HoldTime(hold_time) self.router_id = RouterID(router_id) self.capabilities = capabilities def message (self): if self.asn.asn4(): return self._message("%s%s%s%s%s" % (self.version.pack(),ASN(23456).pack(False),self.hold_time.pack(),self.router_id.pack(),self.capabilities.pack())) return self._message("%s%s%s%s%s" % (self.version.pack(),self.asn.pack(False),self.hold_time.pack(),self.router_id.pack(),self.capabilities.pack())) def __str__ (self): return "OPEN version=%d asn=%d hold_time=%s router_id=%s capabilities=[%s]" % (self.version, self.asn, self.hold_time, self.router_id,self.capabilities)
def unpackFrom(data): type_ = ord(data[0]) & 0x0F stype = ord(data[1]) data = data[2:] if stype == 0x02: #FIXME, unclean if type_ in (0x00, 0x02): asn, number = unpack('!HL', data[:6]) return RouteTarget(ASN(asn), None, number) if type_ == 0x01: ip = socket.inet_ntop(data[0:4]) number = unpack('!H', data[4:6])[0] return RouteTarget(None, ip, number)
def CapabilitiesFactory(self, data): capabilities = Capabilities() option_len = ord(data[0]) if option_len: data = data[1:] while data: key, value, data = self._key_values('parameter', data) # Paramaters must only be sent once. if key == Parameter.AUTHENTIFICATION_INFORMATION: raise Notify(2, 5) if key == Parameter.CAPABILITIES: while value: k, capv, value = self._key_values('capability', value) # Multiple Capabilities can be present in a single attribute #if r: # raise Notify(2,0,"Bad length for OPEN %s (size mismatch) %s" % ('capability',hexa(value))) if k == Capabilities.MULTIPROTOCOL_EXTENSIONS: if k not in capabilities: capabilities[k] = MultiProtocol() afi = AFI(unpack('!H', capv[:2])[0]) safi = SAFI(ord(capv[3])) capabilities[k].append((afi, safi)) continue if k == Capabilities.GRACEFUL_RESTART: restart = unpack('!H', capv[:2])[0] restart_flag = restart >> 12 restart_time = restart & Graceful.TIME_MASK value_gr = capv[2:] families = [] while value_gr: afi = AFI(unpack('!H', value_gr[:2])[0]) safi = SAFI(ord(value_gr[2])) flag_family = ord(value_gr[0]) families.append((afi, safi, flag_family)) value_gr = value_gr[4:] capabilities[k] = Graceful(restart_flag, restart_time, families) continue if k == Capabilities.FOUR_BYTES_ASN: capabilities[k] = ASN(unpack('!L', capv[:4])[0]) continue if k == Capabilities.ROUTE_REFRESH: capabilities[k] = RouteRefresh() continue if k == Capabilities.CISCO_ROUTE_REFRESH: capabilities[k] = CiscoRouteRefresh() continue if k == Capabilities.MULTISESSION_BGP: capabilities[k] = MultiSession() continue if k == Capabilities.MULTISESSION_BGP_RFC: capabilities[k] = MultiSession() continue if k not in capabilities: capabilities[k] = Unknown(k, [ord(_) for _ in capv]) else: raise Notify(2, 0, 'Unknown OPEN parameter %s' % hex(key)) return capabilities
def __init__ (self,version,asn,router_id,capabilities,hold_time): self.version = Version(version) self.asn = ASN(asn) self.hold_time = HoldTime(hold_time) self.router_id = RouterID(router_id) self.capabilities = capabilities