def unpack_nlri(cls, afi, safi, bgp, action, addpath): nlri = cls(afi, safi, action) if addpath: nlri.path_info = PathInfo(bgp[:4]) bgp = bgp[4:] mask = bgp[0] bgp = bgp[1:] _, rd_size = Family.size.get((afi, safi), (0, 0)) rd_mask = rd_size * 8 if safi.has_label(): labels = [] while mask - rd_mask >= 24: label = int(unpack('!L', bytes([0]) + bgp[:3])[0]) bgp = bgp[3:] mask -= 24 # 3 bytes # The last 4 bits are the bottom of Stack # The last bit is set for the last label labels.append(label >> 4) # This is a route withdrawal if label == 0x800000 and action == IN.WITHDRAWN: break # This is a next-hop if label == 0x000000: break if label & 1: break nlri.labels = Labels(labels) if rd_size: mask -= rd_mask # the route distinguisher rd = bgp[:rd_size] bgp = bgp[rd_size:] nlri.rd = RouteDistinguisher(rd) if mask < 0: raise Notify(3, 10, 'invalid length in NLRI prefix') if not bgp and mask: raise Notify( 3, 10, 'not enough data for the mask provided to decode the NLRI') size = CIDR.size(mask) if len(bgp) < size: raise Notify( 3, 10, 'could not decode route with family %s (AFI %d) %s (SAFI %d)' % (AFI(afi), int(afi), SAFI(safi), int(safi))) network, bgp = bgp[:size], bgp[size:] nlri.cidr = CIDR(network + bytes(IP.length(afi) - size), mask) return nlri, bgp
def unpack_nlri(cls, afi, safi, bgp, action, addpath): nlri = cls(afi, safi, action) if addpath: nlri.path_info = PathInfo(bgp[:4]) bgp = bgp[4:] mask = ord(bgp[0]) bgp = bgp[1:] if cls.has_label(): labels = [] while bgp and mask >= 8: label = int(unpack('!L', chr(0) + bgp[:3])[0]) bgp = bgp[3:] mask -= 24 # 3 bytes # The last 4 bits are the bottom of Stack # The last bit is set for the last label labels.append(label >> 4) # This is a route withdrawal if label == 0x800000 and action == IN.WITHDRAWN: break # This is a next-hop if label == 0x000000: break if label & 1: break nlri.labels = Labels(labels) if cls.has_rd(): mask -= 8 * 8 # the 8 bytes of the route distinguisher rd = bgp[:8] bgp = bgp[8:] nlri.rd = RouteDistinguisher(rd) if mask < 0: raise Notify(3, 10, 'invalid length in NLRI prefix') if not bgp and mask: raise Notify( 3, 10, 'not enough data for the mask provided to decode the NLRI') size = CIDR.size(mask) if len(bgp) < size: raise Notify( 3, 10, 'could not decode route with AFI %d sand SAFI %d' % (afi, safi)) network, bgp = bgp[:size], bgp[size:] padding = '\0' * (IP.length(afi) - size) nlri.cidr = CIDR(network + padding, mask) return nlri, bgp
def unpack_nlri (cls, afi, safi, bgp, action, addpath): nlri = cls(afi,safi,action) if addpath: nlri.path_info = PathInfo(bgp[:4]) bgp = bgp[4:] mask = ordinal(bgp[0]) bgp = bgp[1:] _, rd_size = Family.size.get((afi, safi), (0, 0)) rd_mask = rd_size * 8 if safi.has_label(): labels = [] while mask - rd_mask >= 24: label = int(unpack('!L',character(0) + bgp[:3])[0]) bgp = bgp[3:] mask -= 24 # 3 bytes # The last 4 bits are the bottom of Stack # The last bit is set for the last label labels.append(label >> 4) # This is a route withdrawal if label == 0x800000 and action == IN.WITHDRAWN: break # This is a next-hop if label == 0x000000: break if label & 1: break nlri.labels = Labels(labels) if rd_size: mask -= rd_mask # the route distinguisher rd = bgp[:rd_size] bgp = bgp[rd_size:] nlri.rd = RouteDistinguisher(rd) if mask < 0: raise Notify(3,10,'invalid length in NLRI prefix') if not bgp and mask: raise Notify(3,10,'not enough data for the mask provided to decode the NLRI') size = CIDR.size(mask) if len(bgp) < size: raise Notify(3,10,'could not decode route with AFI %d and SAFI %d' % (afi,safi)) network,bgp = bgp[:size],bgp[size:] nlri.cidr = CIDR(network + padding(IP.length(afi)-size),mask) return nlri,bgp
def _nlri(afi, safi, bgp, action, addpath): labels = [] rd = '' if addpath: path_identifier = bgp[:4] bgp = bgp[4:] else: path_identifier = None mask = ord(bgp[0]) bgp = bgp[1:] if SAFI(safi).has_label(): while bgp and mask >= 8: label = int(unpack('!L', chr(0) + bgp[:3])[0]) bgp = bgp[3:] mask -= 24 # 3 bytes # The last 4 bits are the bottom of Stack # The last bit is set for the last label labels.append(label >> 4) # This is a route withdrawal if label == 0x800000 and action == IN.WITHDRAWN: break # This is a next-hop if label == 0x000000: break if label & 1: break if SAFI(safi).has_rd(): mask -= 8 * 8 # the 8 bytes of the route distinguisher rd = bgp[:8] bgp = bgp[8:] if mask < 0: raise Notify(3, 10, 'invalid length in NLRI prefix') if not bgp and mask: raise Notify( 3, 10, 'not enough data for the mask provided to decode the NLRI') size = CIDR.size(mask) if len(bgp) < size: raise Notify( 3, 10, 'could not decode route with AFI %d sand SAFI %d' % (afi, safi)) network, bgp = bgp[:size], bgp[size:] padding = '\0' * (IP.length(afi) - size) prefix = network + padding return labels, rd, path_identifier, mask, size, prefix, bgp
def _nlri (afi, safi, bgp, action, addpath): labels = [] rd = '' if addpath: path_identifier = bgp[:4] bgp = bgp[4:] else: path_identifier = None mask = ord(bgp[0]) bgp = bgp[1:] if SAFI(safi).has_label(): while bgp and mask >= 8: label = int(unpack('!L',chr(0) + bgp[:3])[0]) bgp = bgp[3:] mask -= 24 # 3 bytes # The last 4 bits are the bottom of Stack # The last bit is set for the last label labels.append(label >> 4) # This is a route withdrawal if label == 0x800000 and action == IN.WITHDRAWN: break # This is a next-hop if label == 0x000000: break if label & 1: break if SAFI(safi).has_rd(): mask -= 8*8 # the 8 bytes of the route distinguisher rd = bgp[:8] bgp = bgp[8:] if mask < 0: raise Notify(3,10,'invalid length in NLRI prefix') if not bgp and mask: raise Notify(3,10,'not enough data for the mask provided to decode the NLRI') size = CIDR.size(mask) if len(bgp) < size: raise Notify(3,10,'could not decode route with AFI %d sand SAFI %d' % (afi,safi)) network,bgp = bgp[:size],bgp[size:] padding = '\0'*(IP.length(afi)-size) prefix = network + padding return labels,rd,path_identifier,mask,size,prefix,bgp
def _nlri(afi, safi, bgp, action): labels = [] rd = "" mask = ord(bgp[0]) bgp = bgp[1:] if SAFI(safi).has_label(): while bgp and mask >= 8: label = int(unpack("!L", chr(0) + bgp[:3])[0]) bgp = bgp[3:] mask -= 24 # 3 bytes # The last 4 bits are the bottom of Stack # The last bit is set for the last label labels.append(label >> 4) # This is a route withdrawal if label == 0x800000 and action == IN.withdrawn: break # This is a next-hop if label == 0x000000: break if label & 1: break if SAFI(safi).has_rd(): mask -= 8 * 8 # the 8 bytes of the route distinguisher rd = bgp[:8] bgp = bgp[8:] if mask < 0: raise Notify(3, 10, "invalid length in NLRI prefix") if not bgp and mask: raise Notify(3, 10, "not enough data for the mask provided to decode the NLRI") size = CIDR.size(mask) if len(bgp) < size: raise Notify(3, 10, "could not decode route with AFI %d sand SAFI %d" % (afi, safi)) network, bgp = bgp[:size], bgp[size:] padding = "\0" * (IP.length(afi) - size) prefix = network + padding return labels, rd, mask, size, prefix, bgp
def make(cls, bgp): offset = ord(bgp[1]) prefix, mask = CIDR.decode(AFI.ipv6, bgp[0] + bgp[2:]) return cls(prefix, mask, offset), bgp[CIDR.size(mask) + 2:]
def make(cls, bgp): prefix, mask = CIDR.decode(AFI.ipv4, bgp) return cls(prefix, mask), bgp[CIDR.size(mask) + 1:]
def make (cls, bgp): offset = ord(bgp[1]) prefix,mask = CIDR.decode(AFI.ipv6,bgp[0]+bgp[2:]) return cls(prefix,mask,offset), bgp[CIDR.size(mask)+2:]
def make (cls, bgp): prefix,mask = CIDR.decode(AFI.ipv4,bgp) return cls(prefix,mask), bgp[CIDR.size(mask)+1:]