示例#1
0
    def ReceiveSLI(self, pkt):
        """Receive a SLI packet, handle the AVP.

        :param pkt:
        :return:

        """
        if L2tpv3GlobalSettings.L2tpv3GlobalSettings.MustAvpsCheck is True:
            ret = self.connection.checkMustAvps(
                L2tpv3ControlPacket.L2tpv3ControlPacket.SLIMandatoryAVPs,
                pkt.avps)
            if ret is not True:
                return L2tpv3ControlPacket.L2tpv3CDN(
                    self, 2, 4, "Cannot handle AVP in SLI message")

        self.logger.debug("L2Tp Session[%d, %d] receive a SLI message",
                          self.localSessionId, self.remoteSessionId)
        if len(pkt.avps) > 1:
            for i in xrange(1, len(pkt.avps)):
                avp = pkt.avps[i]
                if not avp.handleAvp(pkt, None):
                    return L2tpv3ControlPacket.L2tpv3CDN(
                        self, 2, 4, "Cannot handle AVP in SLI message")

        return None
示例#2
0
    def ReceiveICCN(self, pkt):
        """Receive a ICCN packet from the connection. Will process the AVPs.

        :param pkt: THe decoded l2tp control packet.
        :return: a ICCN response packet or None

        """
        if L2tpv3GlobalSettings.L2tpv3GlobalSettings.MustAvpsCheck is True:
            ret = self.connection.checkMustAvps(
                L2tpv3ControlPacket.L2tpv3ControlPacket.ICCNMandatoryAVPs,
                pkt.avps)
            if ret is not True:
                self.fsm.recvBadICCN()
                return L2tpv3ControlPacket.L2tpv3CDN(
                    self, 2, 4, "Avp cannot be handled correctly")

        self.logger.debug("L2Tp session[%d, %d] receive a ICCN message",
                          self.localSessionId, self.remoteSessionId)

        if len(pkt.avps) > 1:
            for i in xrange(1, len(pkt.avps)):
                avp = pkt.avps[i]
                # We got a bad ICCN, we should send a CDN
                if not avp.handleAvp(pkt, None):
                    self.fsm.recvBadICCN()
                    return L2tpv3ControlPacket.L2tpv3CDN(
                        self, 2, 4, "Avp cannot be handled correctly")
        self.logger.debug("Session[%d, %d] got a good ICCN, send it to fsm.",
                          self.localSessionId, self.remoteSessionId)
        self.fsm.recvGoodICCN()
        # We need to send the ZLB.
        ackpkt = L2tpv3ControlPacket.L2tpv3ACK(
            connID=self.connection.remoteConnID)
        return ackpkt
示例#3
0
    def _findSession(self, pkt):
        # Find the remote Session
        remoteSessid = 0
        localSessId = 0
        for avp in pkt.avps:
            if isinstance(avp, L2tpv3RFC3931AVPs.LocalSessionID):
                remoteSessid = avp.sessionID
            elif isinstance(avp, L2tpv3RFC3931AVPs.RemoteSessionID):
                localSessId = avp.sessionID

        if not remoteSessid and not localSessId:
            self.logger.warn(
                "Got a packet but no local/remote session ID is set, we cannot send "
                "rsp since we don't know the session ID")
            return None

        # Try to find the session, this is the case sender or some error packet
        # happens
        session1 = self.findSessionByRemoteSessionID(remoteSessid)
        session2 = self.findSessionByLocalSessionID(localSessId)
        if session1 is None and session2 is None:
            # generate a fake session for it, for send the CDN
            session = L2tpv3Session.L2tpv3Session(randint(1, 0xFFFFFFFF),
                                                  remoteSessid, 'receive',
                                                  self)
            cdn = L2tpv3ControlPacket.L2tpv3CDN(
                session, 2, 5, "Cannot find the session in local runtime DB")
            self.transport.SendPacket(cdn)
            return None

        return session1 if session1 else session2
示例#4
0
    def fsmStateRecipientIdle(self, event):
        """Callback function will called when fsm changed to this state.
        CDN is to be sent to remote and remove the session.

        :param event: The event that triggers the fsm to idle state.
        :return:

        """
        self.logger.debug(
            "Session [%d, %d] state is transferred to idle, event:" +
            event.src + " " + event.dst + "  " + event.event,
            self.localSessionId, self.remoteSessionId)
        self.lastchangetime = time.time()
        if event.event == "startup":
            # for startup, ignore it.
            return

        if event.event == L2tpv3Fsm.L2tpv3SessionRecipientFsm.EventRecvCDN and self.connection is not None:
            self.logger.debug(
                "We reach to this state since we receive a CDN, don't need to send the CDN again"
            )
            self.connection.transport.needSendZlb = True
            self.connection.removeSession(self)
            return

        # we should send the CDN to remote
        if event.event == L2tpv3Fsm.L2tpv3SessionRecipientFsm.EventCloseRequest:
            retcode = 3
            errorcode = 0
            msg = "Admin closes the session"

        else:  # fixme we should figure that
            retcode = 3
            errorcode = 0
            msg = "Admin closes the session"

        if self.connection is not None:
            self.logger.debug(
                "Send a CDN to remote since the session is terminated")
            if not self.silentlyCleared:
                transport = self.connection.transport
                cdn = L2tpv3ControlPacket.L2tpv3CDN(self, retcode, errorcode,
                                                    msg)
                transport.SendPacket(cdn, None)
            # Clean up the session
            self.connection.removeSession(self)
示例#5
0
    def ReceiveICRQ(self, pkt):
        """Receive a ICRQ from remote, if it is a good ICRQ, will send a ICRP.

        :param pkt: The ICRQ control packet, has been decoded.
        :return: ICRP packet or None

        """

        if L2tpv3GlobalSettings.L2tpv3GlobalSettings.MustAvpsCheck is True:
            ret = self.connection.checkMustAvps(
                L2tpv3ControlPacket.L2tpv3ControlPacket.ICRQMandatoryAVPs,
                pkt.avps)
            if ret is not True:
                self.fsm.recvBadICRQ()
                return L2tpv3ControlPacket.L2tpv3CDN(
                    self, 2, 4, "Avp cannot be handled correctly")

        self.logger.debug("L2tp session[%d, %d] receives a ICRQ message.",
                          self.localSessionId, self.remoteSessionId)

        avps = list()
        avps.append(
            L2tpv3RFC3931AVPs.ControlMessageAVP(
                L2tpv3RFC3931AVPs.ControlMessageAVP.ICRP))
        avps.append(
            L2tpv3RFC3931AVPs.DataSequencing(
                L2tpv3RFC3931AVPs.DataSequencing.AllSeq))
        # TODO  add sbfd support for ipv6
        if Convert.is_valid_ipv4_address(self.connection.localAddr):
            avps.append(
                L2tpv3RFC3931AVPs.SbfdDiscriminator(
                    int(
                        socket.inet_aton(
                            self.connection.localAddr).encode('hex'), 16)))
            avps.append(
                L2tpv3RFC3931AVPs.SbfdVccv(
                    L2tpv3RFC3931AVPs.SbfdVccv.VccvValue))

        # Need add some Cable labs avp
        self.logger.debug(
            "Session [%d, %d]sends a ICRP packet to remote, connection:%d",
            self.localSessionId, self.remoteSessionId,
            pkt.Connection.remoteConnID)

        icrp = L2tpv3ControlPacket.L2tpv3ControlPacket(
            pkt.Connection.remoteConnID, 0, 0, avps)
        del self.avps_icrq[:]
        del self.mcast[:]
        if len(pkt.avps) > 1:
            for i in xrange(1, len(pkt.avps)):
                avp = pkt.avps[i]
                if isinstance(
                        avp,
                        L2tpv3CableLabsAvps.DepiL2SpecificSublayerSubtype):
                    self.session_l2Sublayer = avp.pw_type
                self.avps_icrq.append(avp)
                # We got a bad ICRQ, we should send a CDN
                if not avp.handleAvp(pkt, icrp):
                    self.fsm.recvBadICRQ()
                    return L2tpv3ControlPacket.L2tpv3CDN(
                        self, 2, 4, "Avp cannot be handled correctly")
        self.logger.debug("We got a good ICRQ, send to fsm")
        self.fsm.recvGoodICRQ()
        return icrp
示例#6
0
    def ReceiveICRP(self, pkt):
        """Receive a ICRP from remote, if it is a good ICRP, will send a ICCN.
        this function will be used for simulator purpose.

        :param pkt: The ICRP control packet, has been decoded.
        :return:

        """
        if L2tpv3GlobalSettings.L2tpv3GlobalSettings.MustAvpsCheck is True:
            ret = self.connection.checkMustAvps(
                L2tpv3ControlPacket.L2tpv3ControlPacket.ICRPMandatoryAVPs,
                pkt.avps)
            if ret is not True:
                if isinstance(self.fsm, L2tpv3Fsm.L2tpv3SessionSenderFsm):
                    self.fsm.recvBadICRP()
                return L2tpv3ControlPacket.L2tpv3CDN(
                    self, 2, 4, "Avp cannot be handled correctly")

        self.logger.debug("Session [%d, %d] gets a l2tp ICRP message.",
                          self.localSessionId, self.remoteSessionId)

        if isinstance(self.fsm, L2tpv3Fsm.L2tpv3SessionRecipientFsm):
            self.logger.debug(
                "Recipient session [%d, %d] gets a l2tp ICRP message.",
                self.localSessionId, self.remoteSessionId)
            self.fsm.recvICRP()
            # this event will trigger the recipient state
            # machine transferring to idle state.
            return

        # Find the local session ID
        for avp in pkt.avps:
            if isinstance(avp, L2tpv3RFC3931AVPs.LocalSessionID):
                self.remoteSessionId = avp.sessionID
                self.connection.addSession(self)

        # If the incoming l2TP ICRP does not contain a local session ID
        if not self.remoteSessionId:
            self.logger.warn(
                "Session[%d, %d] is terminated due to not find the local session ID in ICRP message.",
                self.localSessionId, self.remoteSessionId)
            self.fsm.recvBadICRP()
            return L2tpv3ControlPacket.L2tpv3CDN(self, 2, 5, "")

        # send a ICCN
        msgAvp = L2tpv3RFC3931AVPs.ControlMessageAVP(
            L2tpv3RFC3931AVPs.ControlMessageAVP.ICCN)
        iccn = L2tpv3ControlPacket.L2tpv3ControlPacket(
            self.connection.remoteConnID, avps=(msgAvp, ))
        if len(pkt.avps) > 1:
            for i in xrange(1, len(pkt.avps)):
                avp = pkt.avps[i]
                # We got a bad ICRP, we should send a CDN
                if not avp.handleAvp(pkt, iccn):
                    self.fsm.recvBadICRP()
                    return L2tpv3ControlPacket.L2tpv3CDN(
                        self, 2, 4, "Avp cannot be handled correctly")

        self.logger.debug(
            "Sender session [%d, %d] gets a good l2tp ICRP message.",
            self.localSessionId, self.remoteSessionId)
        self.fsm.recvGoodICRP()
        return iccn