Exemplo n.º 1
0
    def unpack_message(cls, data, negotiated):  # pylint: disable=W0613
        what = Type(unpack('!H', data[0:2])[0])
        length = unpack('!H', data[2:4])[0]

        decode, klass = cls.registered_operational.get(what, ('unknown', None))

        if decode == 'advisory':
            afi = unpack('!H', data[4:6])[0]
            safi = ord_(data[6])
            data = data[7:length + 4]
            return klass(afi, safi, data)
        elif decode == 'query':
            afi = unpack('!H', data[4:6])[0]
            safi = ord_(data[6])
            routerid = RouterID.unpack(data[7:11])
            sequence = unpack('!L', data[11:15])[0]
            return klass(afi, safi, routerid, sequence)
        elif decode == 'counter':
            afi = unpack('!H', data[4:6])[0]
            safi = ord_(data[6])
            routerid = RouterID.unpack(data[7:11])
            sequence = unpack('!L', data[11:15])[0]
            counter = unpack('!L', data[15:19])[0]
            return klass(afi, safi, routerid, sequence, counter)
        else:
            print('ignoring ATM this kind of message')
Exemplo n.º 2
0
	def unpack_message (cls, data, negotiated):  # pylint: disable=W0613
		what = Type(unpack('!H',data[0:2])[0])
		length = unpack('!H',data[2:4])[0]

		decode,klass = cls.registered_operational.get(what,('unknown',None))

		if decode == 'advisory':
			afi = unpack('!H',data[4:6])[0]
			safi = ord_(data[6])
			data = data[7:length+4]
			return klass(afi,safi,data)
		elif decode == 'query':
			afi = unpack('!H',data[4:6])[0]
			safi = ord_(data[6])
			routerid = RouterID.unpack(data[7:11])
			sequence = unpack('!L',data[11:15])[0]
			return klass(afi,safi,routerid,sequence)
		elif decode == 'counter':
			afi = unpack('!H',data[4:6])[0]
			safi = ord_(data[6])
			routerid = RouterID.unpack(data[7:11])
			sequence = unpack('!L',data[11:15])[0]
			counter = unpack('!L',data[15:19])[0]
			return klass(afi,safi,routerid,sequence,counter)
		else:
			print('ignoring ATM this kind of message')
Exemplo n.º 3
0
 def unpack(data, negotiated=None):
     # 30/02/12 Quagga communities for soo and rt are not transitive when 4360 says they must be, hence the & 0x0FFF
     community = (ord_(data[0]) & 0x0F, ord_(data[1]))
     if community in ExtendedCommunity.registered_extended:
         return ExtendedCommunity.registered_extended[community].unpack(
             data)
     return ExtendedCommunity(data)
Exemplo n.º 4
0
    def _new_aspaths(cls, data, asn4, klass=None):
        as_set = []
        as_seq = []
        as_cset = []
        as_cseq = []

        backup = data

        unpacker = {
            False: '!H',
            True: '!L',
        }
        size = {
            False: 2,
            True: 4,
        }
        as_choice = {
            ASPath.AS_SEQUENCE: as_seq,
            ASPath.AS_SET: as_set,
            ASPath.AS_CONFED_SEQUENCE: as_cseq,
            ASPath.AS_CONFED_SET: as_cset,
        }

        upr = unpacker[asn4]
        length = size[asn4]

        try:

            while data:
                stype = ord_(data[0])
                slen = ord_(data[1])

                if stype not in (ASPath.AS_SET, ASPath.AS_SEQUENCE,
                                 ASPath.AS_CONFED_SEQUENCE,
                                 ASPath.AS_CONFED_SET):
                    raise Notify(3, 11, 'invalid AS Path type sent %d' % stype)

                end = 2 + (slen * length)
                sdata = data[2:end]
                data = data[end:]
                # Eat the data and ignore it if the ASPath attribute is know known
                asns = as_choice.get(stype, [])

                for _ in range(slen):
                    asn = unpack(upr, sdata[:length])[0]
                    asns.append(ASN(asn))
                    sdata = sdata[length:]

        except IndexError:
            raise Notify(3, 11,
                         'not enough data to decode AS_PATH or AS4_PATH')
        except error:  # struct
            raise Notify(3, 11,
                         'not enough data to decode AS_PATH or AS4_PATH')

        if klass:
            return klass(as_seq, as_set, as_cseq, as_cset, backup)
        return cls(as_seq, as_set, as_cseq, as_cset, backup)
Exemplo n.º 5
0
	def flag_attribute_content (data):
		flag = Attribute.Flag(ord_(data[0]))
		attr = Attribute.CODE(ord_(data[1]))

		if flag & Attribute.Flag.EXTENDED_LENGTH:
			length = unpack('!H',data[2:4])[0]
			return flag, attr, data[4:length+4]
		else:
			length = ord_(data[2])
			return flag, attr, data[3:length+3]
Exemplo n.º 6
0
    def flag_attribute_content(data):
        flag = Attribute.Flag(ord_(data[0]))
        attr = Attribute.CODE(ord_(data[1]))

        if flag & Attribute.Flag.EXTENDED_LENGTH:
            length = unpack('!H', data[2:4])[0]
            return flag, attr, data[4:length + 4]
        else:
            length = ord_(data[2])
            return flag, attr, data[3:length + 3]
Exemplo n.º 7
0
		def _key_values (name, data):
			if len(data) < 2:
				raise Notify(2,0,"Bad length for OPEN %s (<2) %s" % (name,Capability.hex(data)))
			l = ord_(data[1])
			boundary = l+2
			if len(data) < boundary:
				raise Notify(2,0,"Bad length for OPEN %s (buffer underrun) %s" % (name,Capability.hex(data)))
			key = ord_(data[0])
			value = data[2:boundary]
			rest = data[boundary:]
			return key,value,rest
Exemplo n.º 8
0
	def _new_aspaths (cls, data, asn4, klass=None):
		as_set = []
		as_seq = []
		as_cset = []
		as_cseq = []

		backup = data

		unpacker = {
			False: '!H',
			True:  '!L',
		}
		size = {
			False: 2,
			True:  4,
		}
		as_choice = {
			ASPath.AS_SEQUENCE: as_seq,
			ASPath.AS_SET:      as_set,
			ASPath.AS_CONFED_SEQUENCE: as_cseq,
			ASPath.AS_CONFED_SET:      as_cset,
		}

		upr = unpacker[asn4]
		length = size[asn4]

		try:

			while data:
				stype = ord_(data[0])
				slen  = ord_(data[1])

				if stype not in (ASPath.AS_SET, ASPath.AS_SEQUENCE, ASPath.AS_CONFED_SEQUENCE, ASPath.AS_CONFED_SET):
					raise Notify(3,11,'invalid AS Path type sent %d' % stype)

				end = 2+(slen*length)
				sdata = data[2:end]
				data = data[end:]
				# Eat the data and ignore it if the ASPath attribute is know known
				asns = as_choice.get(stype,[])

				for _ in range(slen):
					asn = unpack(upr,sdata[:length])[0]
					asns.append(ASN(asn))
					sdata = sdata[length:]

		except IndexError:
			raise Notify(3,11,'not enough data to decode AS_PATH or AS4_PATH')
		except error:  # struct
			raise Notify(3,11,'not enough data to decode AS_PATH or AS4_PATH')

		if klass:
			return klass(as_seq,as_set,as_cseq,as_cset,backup)
		return cls(as_seq,as_set,as_cseq,as_cset,backup)
Exemplo n.º 9
0
	def unpack_nlri (cls, afi, safi, bgp, action, addpath):
		length,bgp = ord_(bgp[0]),bgp[1:]

		if length & 0xF0 == 0xF0:  # bigger than 240
			extra,bgp = ord_(bgp[0]),bgp[1:]
			length = ((length & 0x0F) << 16) + extra

		if length > len(bgp):
			raise Notify(3,10,'invalid length at the start of the the flow')

		over = bgp[length:]
		bgp = bgp[:length]

		nlri = cls(afi,safi,action)

		if safi == SAFI.flow_vpn:
			nlri.rd = RouteDistinguisher(bgp[:8])
			bgp = bgp[8:]

		seen = []

		while bgp:
			what,bgp = ord_(bgp[0]),bgp[1:]

			if what not in decode.get(afi,{}):
				raise Notify(3,10,'unknown flowspec component received for address family %d' % what)

			seen.append(what)
			if sorted(seen) != seen:
				raise Notify(3,10,'components are not sent in the right order %s' % seen)

			decoded = decode[afi][what]
			klass = factory[afi][what]

			if decoded == 'prefix':
				adding,bgp = klass.make(bgp)
				if not nlri.add(adding):
					raise Notify(3,10,'components are incompatible (two sources, two destinations, mix ipv4/ipv6) %s' % seen)
				# logger.parser(LazyFormat("added flow %s (%s) payload " % (klass.NAME,adding),bgp[:-len(left)]))
			else:
				end = False
				while not end:
					byte,bgp = ord_(bgp[0]),bgp[1:]
					end = CommonOperator.eol(byte)
					operator = CommonOperator.operator(byte)
					length = CommonOperator.length(byte)
					value,bgp = bgp[:length],bgp[length:]
					adding = klass.decoder(value)
					nlri.add(klass(operator,adding))
					# logger.parser(LazyFormat("added flow %s (%s) operator %d len %d payload " % (klass.NAME,adding,byte,length),value))

		return nlri, bgp+over
Exemplo n.º 10
0
    def unpack(cls, data):
        datalen = len(data)
        rd = RouteDistinguisher.unpack(data[:8])
        esi = ESI.unpack(data[8:18])
        etag = EthernetTag.unpack(data[18:22])
        maclength = ord_(data[22])

        if (maclength > 48 or maclength < 0):
            raise Notify(3, 5, 'invalid MAC Address length in %s' % cls.NAME)
        end = 23 + 6  # MAC length MUST be 6

        mac = MACQUAL.unpack(data[23:end])

        length = ord_(data[end])
        iplen = length / 8

        if datalen in [33, 36]:  # No IP information (1 or 2 labels)
            iplenUnpack = 0
            if iplen != 0:
                raise Notify(
                    3, 5,
                    "IP length is given as %d, but current MAC route has no IP information"
                    % iplen)
        elif datalen in [37, 40]:  # Using IPv4 addresses (1 or 2 labels)
            iplenUnpack = 4
            if (iplen > 32 or iplen < 0):
                raise Notify(
                    3, 5,
                    "IP field length is given as %d, but current MAC route is IPv4 and valus is out of range"
                    % iplen)
        elif datalen in [49, 52]:  # Using IPv6 addresses (1 or 2 labels)
            iplenUnpack = 16
            if (iplen > 128 or iplen < 0):
                raise Notify(
                    3, 5,
                    "IP field length is given as %d, but current MAC route is IPv6 and valus is out of range"
                    % iplen)
        else:
            raise Notify(
                3, 5,
                "Data field length is given as %d, but does not match one of the expected lengths"
                % datalen)

        payload = data[end + 1:end + 1 + iplenUnpack]
        if payload:
            ip = IP.unpack(data[end + 1:end + 1 + iplenUnpack])
        else:
            ip = None
        label = Labels.unpack(data[end + 1 + iplenUnpack:end + 1 +
                                   iplenUnpack + 3])

        return cls(rd, esi, etag, mac, maclength, label, ip, data)
Exemplo n.º 11
0
Arquivo: nlri.py Projeto: qoke/exabgp
    def unpack_nlri(cls, afi, safi, bgp, action, addpath):
        code = ord_(bgp[0])
        length = ord_(bgp[1])

        if code in cls.registered_evpn:
            klass = cls.registered_evpn[code].unpack(bgp[2:length + 2])
        else:
            klass = GenericEVPN(code, bgp[2:length + 2])
        klass.CODE = code
        klass.action = action
        klass.addpath = addpath

        return klass, bgp[length + 2:]
Exemplo n.º 12
0
	def unpack_nlri (cls, afi, safi, bgp, action, addpath):
		code = ord_(bgp[0])
		length = ord_(bgp[1])

		if code in cls.registered_evpn:
			klass = cls.registered_evpn[code].unpack(bgp[2:length+2])
		else:
			klass = GenericEVPN(code,bgp[2:length+2])
		klass.CODE = code
		klass.action = action
		klass.addpath = addpath

		return klass,bgp[length+2:]
Exemplo n.º 13
0
	def unpack (data):
		def _key_values (name, data):
			if len(data) < 2:
				raise Notify(2,0,"Bad length for OPEN %s (<2) %s" % (name,Capability.hex(data)))
			l = ord_(data[1])
			boundary = l+2
			if len(data) < boundary:
				raise Notify(2,0,"Bad length for OPEN %s (buffer underrun) %s" % (name,Capability.hex(data)))
			key = ord_(data[0])
			value = data[2:boundary]
			rest = data[boundary:]
			return key,value,rest

		capabilities = Capabilities()

		option_len = ord_(data[0])
		if not option_len:
			return capabilities

		data = data[1:option_len+1]
		while data:
			key,value,data = _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:
					capability,capv,value = _key_values('capability',value)
					capabilities[capability] = Capability.unpack(capability,capabilities,capv)
			else:
				raise Notify(2,0,'Unknow OPEN parameter %s' % hex(key))
		return capabilities
Exemplo n.º 14
0
	def unpack (cls, exdata):
		data = exdata

		# Get the data length to understand if addresses are IPv4 or IPv6
		datalen = len(data)

		rd = RouteDistinguisher.unpack(data[:8])
		data = data[8:]

		esi = ESI.unpack(data[:10])
		data = data[10:]

		etag = EthernetTag.unpack(data[:4])
		data = data[4:]

		iplen = ord_(data[0])
		data = data[1:]

		if datalen == (26 + 8):  # Using IPv4 addresses
			ip = IP.unpack(data[:4])
			data = data[4:]
			gwip = IP.unpack(data[:4])
			data = data[4:]
		elif datalen == (26 + 32):  # Using IPv6 addresses
			ip = IP.unpack(data[:16])
			data = data[16:]
			gwip = IP.unpack(data[:16])
			data = data[16:]
		else:
			raise Notify(3,5,"Data field length is given as %d, but EVPN route currently support only IPv4 or IPv6(34 or 58)" % datalen)

		label = Labels.unpack(data[:3])

		return cls(rd,esi,etag,label,ip,iplen,gwip,exdata)
Exemplo n.º 15
0
	def unpack (data, negotiated):
		communities = ExtendedCommunities()
		while data:
			if data and len(data) < 8:
				raise Notify(3,1,'could not decode extended community %s' % str([hex(ord_(_)) for _ in data]))
			communities.add(ExtendedCommunity.unpack(data[:8],negotiated))
			data = data[8:]
		return communities
Exemplo n.º 16
0
	def decode (afi,bgp):
		mask = ord_(bgp[0])
		size = CIDR.size(mask)

		if len(bgp) < size+1:
			raise Notify(3,10,'could not decode CIDR')

		return bgp[1:size+1] + padding(IP.length(afi)-size), mask
Exemplo n.º 17
0
	def pack (self, negotiated=None):
		# XXX: no support for addpath yet
		# We reset ext com flag bits from the first byte in the packed RT
		# because in an RTC route these flags never appear.
		if self.rt:
			packedRT = self.rt.pack()
			return pack("!BLB", len(self), self.origin, ord_(RTC.resetFlags(packedRT[0]))) + packedRT[1:]
		return pack("!B",0)
Exemplo n.º 18
0
	def unpack (cls, data):
		rd = RouteDistinguisher.unpack(data[:8])
		etag = EthernetTag.unpack(data[8:12])
		iplen = ord_(data[12])
		if iplen not in (4*8,16*8):
			raise Exception("IP len is %d, but EVPN route currently support only IPv4" % iplen)
		ip = IP.unpack(data[13:13+iplen//8])
		return cls(rd,etag,ip,data)
Exemplo n.º 19
0
 def pack(self, negotiated=None):
     # XXX: no support for addpath yet
     # We reset ext com flag bits from the first byte in the packed RT
     # because in an RTC route these flags never appear.
     if self.rt:
         packedRT = self.rt.pack()
         return pack("!BLB", len(self), self.origin,
                     ord_(RTC.resetFlags(packedRT[0]))) + packedRT[1:]
     return pack("!B", 0)
Exemplo n.º 20
0
	def unpack_capability (instance, data, capability=None):  # pylint: disable=W0613
		# XXX: FIXME: should check that we have not yet seen the capability
		while data:
			afi = AFI.unpack(data[:2])
			safi = SAFI.unpack(data[2])
			sr = ord_(data[3])
			instance.add_path(afi,safi,sr)
			data = data[4:]
		return instance
Exemplo n.º 21
0
 def unpack(data, negotiated):
     communities = ExtendedCommunities()
     while data:
         if data and len(data) < 8:
             raise Notify(
                 3, 1, 'could not decode extended community %s' %
                 str([hex(ord_(_)) for _ in data]))
         communities.add(ExtendedCommunity.unpack(data[:8], negotiated))
         data = data[8:]
     return communities
Exemplo n.º 22
0
 def unpack(data, negotiated):
     communities = Communities()
     while data:
         if data and len(data) < 4:
             raise Notify(
                 3, 1, 'could not decode community %s' %
                 str([hex(ord_(_)) for _ in data]))
         communities.add(Community.unpack(data[:4], negotiated))
         data = data[4:]
     return communities
Exemplo n.º 23
0
Arquivo: inet.py Projeto: qoke/exabgp
    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:]

        nlri.cidr = CIDR(network + padding(IP.length(afi) - size), mask)

        return nlri, bgp
Exemplo n.º 24
0
	def unpack (data, negotiated):
		large_communities = LargeCommunities()
		while data:
			if data and len(data) < 12:
				raise Notify(3,1,'could not decode large community %s' % str([hex(ord_(_)) for _ in data]))
			lc = LargeCommunity.unpack(data[:12],negotiated)
			data = data[12:]
			if lc in large_communities.communities:
				continue
			large_communities.add(lc)
		return large_communities
Exemplo n.º 25
0
	def unpack (cls, data):
		rd = RouteDistinguisher.unpack(data[:8])
		esi = ESI.unpack(data[8:18])
		iplen = ord_(data[18])

		if iplen not in (32,128):
			raise Notify(3,5,"IP length field is given as %d in current Segment, expecting 32 (IPv4) or 128 (IPv6) bits" % iplen)

		ip = IP.unpack(data[19:19+(iplen/8)])

		return cls(rd,esi,ip,data)
Exemplo n.º 26
0
 def unpack(data, negotiated):
     large_communities = LargeCommunities()
     while data:
         if data and len(data) < 12:
             raise Notify(
                 3, 1, 'could not decode large community %s' %
                 str([hex(ord_(_)) for _ in data]))
         lc = LargeCommunity.unpack(data[:12], negotiated)
         data = data[12:]
         if lc in large_communities.communities:
             continue
         large_communities.add(lc)
     return large_communities
Exemplo n.º 27
0
	def unpack (cls, data):
		datalen = len(data)
		rd = RouteDistinguisher.unpack(data[:8])
		esi = ESI.unpack(data[8:18])
		etag = EthernetTag.unpack(data[18:22])
		maclength = ord_(data[22])

		if (maclength > 48 or maclength < 0):
			raise Notify(3,5,'invalid MAC Address length in %s' % cls.NAME)
		end = 23 + 6 # MAC length MUST be 6

		mac = MACQUAL.unpack(data[23:end])

		length = ord_(data[end])
		iplen = length / 8

		if datalen in [33,36]:  # No IP information (1 or 2 labels)
			iplenUnpack = 0
			if iplen != 0:
				raise Notify(3,5,"IP length is given as %d, but current MAC route has no IP information" % iplen)
		elif datalen in [37, 40]:  # Using IPv4 addresses (1 or 2 labels)
			iplenUnpack = 4
			if (iplen > 32 or iplen < 0):
				raise Notify(3,5,"IP field length is given as %d, but current MAC route is IPv4 and valus is out of range" % iplen)
		elif datalen in [49, 52]:  # Using IPv6 addresses (1 or 2 labels)
			iplenUnpack = 16
			if (iplen > 128 or iplen < 0):
				raise Notify(3,5,"IP field length is given as %d, but current MAC route is IPv6 and valus is out of range" % iplen)
		else:
			raise Notify(3,5,"Data field length is given as %d, but does not match one of the expected lengths" % datalen)

		payload = data[end+1:end+1+iplenUnpack]
		if payload:
			ip = IP.unpack(data[end+1:end+1+iplenUnpack])
		else:
			ip = None
		label = Labels.unpack(data[end+1+iplenUnpack:end+1+iplenUnpack+3])

		return cls(rd,esi,etag,mac,maclength,label,ip,data)
Exemplo n.º 28
0
	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 and SAFI %d' % (afi,safi))

		network,bgp = bgp[:size],bgp[size:]

		nlri.cidr = CIDR(network + padding(IP.length(afi)-size),mask)

		return nlri,bgp
Exemplo n.º 29
0
    def unpack(cls, data):
        rd = RouteDistinguisher.unpack(data[:8])
        esi = ESI.unpack(data[8:18])
        iplen = ord_(data[18])

        if iplen not in (32, 128):
            raise Notify(
                3, 5,
                "IP field length is given as %d in current Segment, expecting 32 (IPv4) or 128 (IPv6) bits"
                % iplen)

        ip = IP.unpack(data[19:19 + (iplen / 8)])

        return cls(rd, esi, ip, data)
Exemplo n.º 30
0
	def unpack_capability (instance, data, capability=None):  # pylint: disable=W0613
		# XXX: FIXME: should raise if instance was already setup
		restart = unpack('!H',data[:2])[0]
		restart_flag = restart >> 12
		restart_time = restart & Graceful.TIME_MASK
		data = data[2:]
		families = []
		while data:
			afi = AFI.unpack(data[:2])
			safi = SAFI.unpack(data[2])
			flag_family = ord_(data[3])
			families.append((afi,safi,flag_family))
			data = data[4:]
		return instance.set(restart_flag,restart_time,families)
Exemplo n.º 31
0
	def unpack_message (cls, data, _=None):
		version = ord_(data[0])
		if version != 4:
			# Only version 4 is supported nowdays..
			raise Notify(2,1,data[0])
		asn = unpack('!H',data[1:3])[0]
		hold_time = unpack('!H',data[3:5])[0]
		numeric = unpack('!L',data[5:9])[0]
		router_id = "%d.%d.%d.%d" % (numeric >> 24,(numeric >> 16) & 0xFF,(numeric >> 8) & 0xFF,numeric & 0xFF)
		return cls(
			Version(version),
			ASN(asn),
			HoldTime(hold_time),
			RouterID(router_id),
			Capabilities.unpack(data[9:])
		)
Exemplo n.º 32
0
    def unpack_nlri(cls, afi, safi, bgp, action, addpath):

        length = ord_(bgp[0])

        if length == 0:
            return cls(afi, safi, action, ASN(0), None), bgp[1:]

        if length < 8 * 4:
            raise Exception("incorrect RT lenght: %d (should be >=32,<=96)" %
                            length)

        # We are reseting the flags on the RouteTarget extended
        # community, because they do not make sense for an RTC route

        return cls(afi, safi, action, ASN(unpack('!L', bgp[1:5])[0]),
                   RouteTarget.unpack(RTC.resetFlags(bgp[5]) +
                                      bgp[6:13])), bgp[13:]
Exemplo n.º 33
0
    def __init__(self, code, subcode, data=b''):
        self.code = code
        self.subcode = subcode

        if not (code, subcode) in [(6, 2), (6, 4)]:
            self.data = data if not len(
                [_ for _ in data
                 if _ not in string.printable]) else hexstring(data)
            return

        if len(data) == 0:
            # shutdown without shutdown communication (the old fashioned way)
            self.data = b''
            return

        # draft-ietf-idr-shutdown or the peer was using 6,2 with data

        shutdown_length = ord_(data[0])
        data = data[1:]

        if shutdown_length == 0:
            self.data = "empty Shutdown Communication."
            # move offset past length field
            return

        if len(data) < shutdown_length:
            self.data = "invalid Shutdown Communication (buffer underrun) length : %i [%s]" % (
                shutdown_length, hexstring(data))
            return

        if shutdown_length > 128:
            self.data = "invalid Shutdown Communication (too large) length : %i [%s]" % (
                shutdown_length, hexstring(data))
            return

        try:
            self.data = 'Shutdown Communication: "%s"' % \
             data[:shutdown_length].decode('utf-8').replace('\r',' ').replace('\n',' ')
        except UnicodeDecodeError:
            self.data = "invalid Shutdown Communication (invalid UTF-8) length : %i [%s]" % (
                shutdown_length, hexstring(data))
            return

        trailer = data[shutdown_length:]
        if trailer:
            self.data += ", trailing data: " + hexstring(trailer)
Exemplo n.º 34
0
	def unpack_nlri (cls, afi, safi, bgp, action, addpath):

		length = ord_(bgp[0])

		if length == 0:
			return cls(afi,safi,action,ASN(0),None),bgp[1:]

		if length < 8*4:
			raise Exception("incorrect RT length: %d (should be >=32,<=96)" % length)

		# We are reseting the flags on the RouteTarget extended
		# community, because they do not make sense for an RTC route

		return cls(
			afi, safi, action,
			ASN(unpack('!L', bgp[1:5])[0]),
			RouteTarget.unpack(
				RTC.resetFlags(bgp[5])+bgp[6:13]
			)
		),bgp[13:]
Exemplo n.º 35
0
	def __init__ (self, code, subcode, data=b''):
		self.code = code
		self.subcode = subcode

		if not (code, subcode) in [(6, 2), (6, 4)]:
			self.data = data if not len([_ for _ in data if _ not in string.printable]) else hexstring(data)
			return

		if len(data) == 0:
			# shutdown without shutdown communication (the old fashioned way)
			self.data = b''
			return

		# draft-ietf-idr-shutdown or the peer was using 6,2 with data

		shutdown_length  = ord_(data[0])
		data = data[1:]

		if shutdown_length == 0:
			self.data = "empty Shutdown Communication."
			# move offset past length field
			return

		if len(data) < shutdown_length:
			self.data = "invalid Shutdown Communication (buffer underrun) length : %i [%s]" % (shutdown_length, hexstring(data))
			return

		if shutdown_length > 128:
			self.data = "invalid Shutdown Communication (too large) length : %i [%s]" % (shutdown_length, hexstring(data))
			return

		try:
			self.data = 'Shutdown Communication: "%s"' % \
				data[:shutdown_length].decode('utf-8').replace('\r',' ').replace('\n',' ')
		except UnicodeDecodeError:
			self.data = "invalid Shutdown Communication (invalid UTF-8) length : %i [%s]" % (shutdown_length, hexstring(data))
			return

		trailer = data[shutdown_length:]
		if trailer:
			self.data += ", trailing data: " + hexstring(trailer)
Exemplo n.º 36
0
    def unpack(cls, exdata):
        data = exdata

        # Get the data length to understand if addresses are IPv4 or IPv6
        datalen = len(data)

        rd = RouteDistinguisher.unpack(data[:8])
        data = data[8:]

        esi = ESI.unpack(data[:10])
        data = data[10:]

        etag = EthernetTag.unpack(data[:4])
        data = data[4:]

        iplen = ord_(data[0])
        data = data[1:]

        if datalen == (26 + 8):  # Using IPv4 addresses
            ip = IP.unpack(data[:4])
            data = data[4:]
            gwip = IP.unpack(data[:4])
            data = data[4:]
        elif datalen == (26 + 32):  # Using IPv6 addresses
            ip = IP.unpack(data[:16])
            data = data[16:]
            gwip = IP.unpack(data[:16])
            data = data[16:]
        else:
            raise Notify(
                3, 5,
                "Data field length is given as %d, but EVPN route currently support only IPv4 or IPv6(34 or 58)"
                % datalen)

        label = Labels.unpack(data[:3])

        return cls(rd, esi, etag, label, ip, iplen, gwip, exdata)
Exemplo n.º 37
0
	def __str__ (self):
		return "evpn:%s:%s" % (self.registered_evpn.get(self.CODE,self).SHORT_NAME.lower(),'0x' + ''.join('%02x' % ord_(_) for _ in self._packed))
Exemplo n.º 38
0
	def unpack (data, negotiated=None):
		# 30/02/12 Quagga communities for soo and rt are not transitive when 4360 says they must be, hence the & 0x0FFF
		community = (ord_(data[0]) & 0x0F,ord_(data[1]))
		if community in ExtendedCommunity.registered_extended:
			return ExtendedCommunity.registered_extended[community].unpack(data)
		return ExtendedCommunity(data)
Exemplo n.º 39
0
 def __repr__(self):
     return '0x' + ''.join('%02x' % ord_(_) for _ in self.data)
Exemplo n.º 40
0
 def __str__(self):
     return ':'.join('%02X' % ord_(_) for _ in self._packed)
Exemplo n.º 41
0
	def unpack (cls, data, negotiated):
		return cls(ord_(data),data)
Exemplo n.º 42
0
 def resetFlags(char):
     return chr_(
         ord_(char)
         & ~(Attribute.Flag.TRANSITIVE | Attribute.Flag.OPTIONAL))
Exemplo n.º 43
0
 def hex(data):
     return '0x' + b''.join('%02x' % ord_(_) for _ in data)
Exemplo n.º 44
0
	def resetFlags(char):
		return chr_(ord_(char) & ~(Attribute.Flag.TRANSITIVE | Attribute.Flag.OPTIONAL))
Exemplo n.º 45
0
Arquivo: nlri.py Projeto: qoke/exabgp
 def __str__(self):
     return "evpn:%s:%s" % (self.registered_evpn.get(
         self.CODE,
         self).SHORT_NAME.lower(), '0x' + ''.join('%02x' % ord_(_)
                                                  for _ in self._packed))
Exemplo n.º 46
0
	def prettytunnel (self):
		return "0x" + ''.join('%02X' % ord_(_) for _ in self.tunnel) if self.tunnel else ''
Exemplo n.º 47
0
	def _raw (self):
		return ''.join('%02X' % ord_(_) for _ in self.pack())
Exemplo n.º 48
0
	def __repr__ (self):
		return '0x' + ''.join('%02x' % ord_(_) for _ in self.data)
Exemplo n.º 49
0
	def json (self):
		h = 0x00
		for byte in self.community:
			h <<= 8
			h += ord_(byte)
		return "%ld" % h
Exemplo n.º 50
0
	def unpack (cls, data, negotiated):
		nlris = []

		# -- Reading AFI/SAFI
		afi,safi = unpack('!HB',data[:3])
		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 %d/%d' % (afi,safi))

		# -- Reading length of next-hop
		len_nh = ord_(data[offset])
		offset += 1

		rd = 0

		# check next-hop size
		if afi == AFI.ipv4:
			if safi in (SAFI.unicast,SAFI.multicast):
				if len_nh != 4:
					raise Notify(3,0,'invalid ipv4 unicast/multicast next-hop length %d expected 4' % len_nh)
			elif safi in (SAFI.mpls_vpn,):
				if len_nh != 12:
					raise Notify(3,0,'invalid ipv4 mpls_vpn next-hop length %d expected 12' % len_nh)
				rd = 8
			elif safi in (SAFI.flow_ip,):
				if len_nh not in (0,4):
					raise Notify(3,0,'invalid ipv4 flow_ip next-hop length %d expected 4' % len_nh)
			elif safi in (SAFI.flow_vpn,):
				if len_nh not in (0,4):
					raise Notify(3,0,'invalid ipv4 flow_vpn next-hop length %d expected 4' % len_nh)
			elif safi in (SAFI.rtc,):
				if len_nh not in (4,16):
					raise Notify(3,0,'invalid ipv4 rtc next-hop length %d expected 4' % len_nh)
		elif afi == AFI.ipv6:
			if safi in (SAFI.unicast,):
				if len_nh not in (16,32):
					raise Notify(3,0,'invalid ipv6 unicast next-hop length %d expected 16 or 32' % len_nh)
			elif safi in (SAFI.mpls_vpn,):
				if len_nh not in (24,40):
					raise Notify(3,0,'invalid ipv6 mpls_vpn next-hop length %d expected 24 or 40' % len_nh)
				rd = 8
			elif safi in (SAFI.flow_ip,):
				if len_nh not in (0,16,32):
					raise Notify(3,0,'invalid ipv6 flow_ip next-hop length %d expected 0, 16 or 32' % len_nh)
			elif safi in (SAFI.flow_vpn,):
				if len_nh not in (0,16,32):
					raise Notify(3,0,'invalid ipv6 flow_vpn next-hop length %d expected 0, 16 or 32' % len_nh)
		elif afi == AFI.l2vpn:
			if len_nh != 4:
				Notify(3,0,'invalid l2vpn next-hop length %d expected 4' % len_nh)
		elif afi == AFI.bgpls:
			if len_nh != 4:
				Notify(3,0,'invalid bgpls next-hop length %d expected 4' % len_nh)
		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(ord_(_)) 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 = ord_(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")

			# logger.parser(LazyFormat("parsed announce mp nlri %s payload " % nlri,data[:length]))
			data = left
		return cls(afi,safi,nlris)
Exemplo n.º 51
0
	def __repr__ (self):
		h = 0x00
		for byte in self.community:
			h <<= 8
			h += ord_(byte)
		return "0x%016X" % h
Exemplo n.º 52
0
Arquivo: nlri.py Projeto: qoke/exabgp
 def _raw(self):
     return ''.join('%02X' % ord_(_) for _ in self.pack())
Exemplo n.º 53
0
	def unpack (cls, data):
		return cls(':'.join('%02X' % ord_(_) for _ in data[:6]),data[:6])
Exemplo n.º 54
0
	def __str__ (self):
		return ':'.join('%02X' % ord_(_) for _ in self._packed)
Exemplo n.º 55
0
 def unpack(cls, data, negotiated):
     if data:
         raise Notify(
             3, 2,
             'invalid ATOMIC_AGGREGATE %s' % [hex(ord_(_)) for _ in data])
     return cls()