def unpack(cls, data, direction, negotiated): nlris = [] # -- Reading AFI/SAFI afi, safi = unpack('!HB', data[:3]) offset = 3 data = data[offset:] if negotiated and (afi, safi) not in negotiated.families: raise Notify( 3, 0, 'presented a non-negotiated family %s %s' % (AFI.create(afi), SAFI.create(safi))) # Do we need to handle Path Information with the route (AddPath) if direction == Direction.IN: addpath = negotiated.addpath.receive(afi, safi) else: addpath = negotiated.addpath.send(afi, safi) while data: nlri, data = NLRI.unpack_nlri(afi, safi, data, IN.WITHDRAWN, addpath) # allow unpack_nlri to return none for "treat as withdraw" controlled by NLRI.unpack_nlri if nlri: nlris.append(nlri) return cls(afi, safi, nlris)
def unpack_nlri(cls, afi, safi, data, action, addpath): a, s = AFI.create(afi), SAFI.create(safi) log.debug(LazyNLRI(a, s, addpath, data), 'parser') key = '%s/%s' % (a, s) if key in cls.registered_nlri: return cls.registered_nlri[key].unpack_nlri(a, s, data, action, addpath) raise Notify(3, 0, 'trying to decode unknown family %s/%s' % (a, s))
def unpack_nlri(cls, afi, safi, data, action, addpath): if not cls.logger: cls.logger = Logger() cls.logger.parser(LazyNLRI(afi, safi, addpath, data)) a, s = AFI.create(afi), SAFI.create(safi) key = '%s/%s' % (a, s) if key in cls.registered_nlri: return cls.registered_nlri[key].unpack_nlri( afi, safi, data, action, addpath) raise Notify(3, 0, 'trying to decode unknown family %s/%s' % (a, s))
def unpack_nlri (cls, afi, safi, data, action, addpath): if not cls.logger: cls.logger = Logger() a,s = AFI.create(afi),SAFI.create(safi) cls.logger.debug(LazyNLRI(a,s,addpath,data),'parser') key = '%s/%s' % (a, s) if key in cls.registered_nlri: return cls.registered_nlri[key].unpack_nlri(a,s,data,action,addpath) raise Notify(3,0,'trying to decode unknown family %s/%s' % (a,s))
def register_nlri(klass): new = (AFI.create(afi), SAFI.create(safi)) if new in cls.registered_nlri: if force: # python has a bug and does not allow %ld/%ld (pypy does) cls.registered_nlri['%s/%s' % new] = klass else: raise RuntimeError('Tried to register %s/%s twice' % new) else: # python has a bug and does not allow %ld/%ld (pypy does) cls.registered_nlri['%s/%s' % new] = klass cls.registered_families.append(new) return klass
def register_nlri (klass): new = (AFI.create(afi),SAFI.create(safi)) if new in cls.registered_nlri: if force: # python has a bug and does not allow %ld/%ld (pypy does) cls.registered_nlri['%s/%s' % new] = klass else: raise RuntimeError('Tried to register %s/%s twice' % new) else: # python has a bug and does not allow %ld/%ld (pypy does) cls.registered_nlri['%s/%s' % new] = klass cls.registered_families.append(new) return klass
def unpack (cls, data, negotiated): nlris = [] # -- Reading AFI/SAFI afi,safi = unpack('!HB',data[:3]) offset = 3 data = data[offset:] if negotiated and (afi,safi) not in negotiated.families: raise Notify(3,0,'presented a non-negotiated family %s %s' % (AFI.create(afi),SAFI.create(safi))) # Is the peer going to send us some Path Information with the route (AddPath) addpath = negotiated.addpath.receive(afi,safi) while data: nlri,data = NLRI.unpack_nlri(afi,safi,data,IN.WITHDRAWN,addpath) nlris.append(nlri) return cls(afi,safi,nlris)
def __init__ (self, what, afi, safi, data=b''): Operational.__init__(self,what) self.afi = AFI.create(afi) self.safi = SAFI.create(safi) self.data = data
def __init__(self, what, afi, safi, data=b''): Operational.__init__(self, what) self.afi = AFI.create(afi) self.safi = SAFI.create(safi) self.data = data
def unpack(cls, data, negotiated): nlris = [] # -- Reading AFI/SAFI _afi, _safi = unpack('!HB', data[:3]) afi, safi = AFI.create(_afi), SAFI.create(_safi) offset = 3 # we do not want to accept unknown families if negotiated and (afi, safi) not in negotiated.families: raise Notify( 3, 0, 'presented a non-negotiated family %s/%s' % (afi, safi)) # -- Reading length of next-hop len_nh = ordinal(data[offset]) offset += 1 if (afi, safi) not in Family.size: raise Notify(3, 0, 'unsupported %s %s' % (afi, safi)) length, rd = Family.size[(afi, safi)] if len_nh not in length: raise Notify( 3, 0, 'invalid %s %s next-hop length %d expected %s' % (afi, safi, len_nh, ' or '.join(str(_) for _ in length))) size = len_nh - rd # XXX: FIXME: GET IT FROM CACHE HERE ? nhs = data[offset + rd:offset + rd + size] nexthops = [nhs[pos:pos + 16] for pos in range(0, len(nhs), 16)] # chech the RD is well zero if rd and sum([int(ordinal(_)) for _ in data[offset:8]]) != 0: raise Notify( 3, 0, "MP_REACH_NLRI next-hop's route-distinguisher must be zero") offset += len_nh # Skip a reserved bit as somone had to bug us ! reserved = ordinal(data[offset]) offset += 1 if reserved != 0: raise Notify(3, 0, 'the reserved bit of MP_REACH_NLRI is not zero') # Is the peer going to send us some Path Information with the route (AddPath) addpath = negotiated.addpath.receive(afi, safi) # Reading the NLRIs data = data[offset:] if not data: raise Notify( 3, 0, 'No data to decode in an MPREACHNLRI but it is not an EOR %d/%d' % (afi, safi)) while data: if nexthops: for nexthop in nexthops: nlri, left = NLRI.unpack_nlri(afi, safi, data, IN.ANNOUNCED, addpath) # allow unpack_nlri to return none for "treat as withdraw" controlled by NLRI.unpack_nlri if nlri: nlri.nexthop = NextHop.unpack(nexthop) nlris.append(nlri) else: nlri, left = NLRI.unpack_nlri(afi, safi, data, IN.ANNOUNCED, addpath) # allow unpack_nlri to return none for "treat as withdraw" controlled by NLRI.unpack_nlri if nlri: nlris.append(nlri) if left == data: raise RuntimeError("sub-calls should consume data") data = left return cls(afi, safi, nlris)
def __init__ (self, afi, safi, reserved=0): self.afi = AFI.create(afi) self.safi = SAFI.create(safi) self.reserved = Reserved(reserved)
def unpack (cls, data, negotiated): nlris = [] # -- Reading AFI/SAFI _afi,_safi = unpack('!HB',data[:3]) afi,safi = AFI.create(_afi),SAFI.create(_safi) offset = 3 # we do not want to accept unknown families if negotiated and (afi,safi) not in negotiated.families: raise Notify(3,0,'presented a non-negotiated family %s/%s' % (afi,safi)) # -- Reading length of next-hop len_nh = ordinal(data[offset]) offset += 1 if (afi,safi) not in Family.size: raise Notify(3,0,'unsupported %s %s' % (afi,safi)) length,rd = Family.size[(afi,safi)] if len_nh not in length: raise Notify(3,0,'invalid %s %s next-hop length %d expected %s' % (afi,safi,len_nh,' or '.join(str(_) for _ in length))) size = len_nh - rd # XXX: FIXME: GET IT FROM CACHE HERE ? nhs = data[offset+rd:offset+rd+size] nexthops = [nhs[pos:pos+16] for pos in range(0,len(nhs),16)] # chech the RD is well zero if rd and sum([int(ordinal(_)) for _ in data[offset:8]]) != 0: raise Notify(3,0,"MP_REACH_NLRI next-hop's route-distinguisher must be zero") offset += len_nh # Skip a reserved bit as somone had to bug us ! reserved = ordinal(data[offset]) offset += 1 if reserved != 0: raise Notify(3,0,'the reserved bit of MP_REACH_NLRI is not zero') # Is the peer going to send us some Path Information with the route (AddPath) addpath = negotiated.addpath.receive(afi,safi) # Reading the NLRIs data = data[offset:] if not data: raise Notify(3,0,'No data to decode in an MPREACHNLRI but it is not an EOR %d/%d' % (afi,safi)) while data: if nexthops: for nexthop in nexthops: nlri,left = NLRI.unpack_nlri(afi,safi,data,IN.ANNOUNCED,addpath) nlri.nexthop = NextHop.unpack(nexthop) nlris.append(nlri) else: nlri,left = NLRI.unpack_nlri(afi,safi,data,IN.ANNOUNCED,addpath) nlris.append(nlri) if left == data: raise RuntimeError("sub-calls should consume data") data = left return cls(afi,safi,nlris)