Exemplo n.º 1
0
static void
CcpLayerFinish(struct fsm *fp)
{
  /* We're now down */
  struct ccp *ccp = fsm2ccp(fp);
  struct ccp_opt *next;

  log_Printf(LogCCP, "%s: LayerFinish.\n", fp->link->name);

  /*
   * Nuke options that may be left over from sending a REQ but never
   * coming up.
   */
  while (ccp->out.opt) {
    next = ccp->out.opt->next;
    free(ccp->out.opt);
    ccp->out.opt = next;
  }

  if (ccp_Required(ccp)) {
    if (fp->link->lcp.fsm.state == ST_OPENED)
      log_Printf(LogLCP, "%s: Closing due to CCP completion\n", fp->link->name);
    fsm_Close(&fp->link->lcp.fsm);
  }
}
Exemplo n.º 2
0
void
datalink_AuthNotOk(struct datalink *dl)
{
  datalink_NewState(dl, DATALINK_LCP);
  datalink_AuthReInit(dl);
  fsm_Close(&dl->physical->link.lcp.fsm);
}
Exemplo n.º 3
0
void
datalink_Close(struct datalink *dl, int how)
{
  /* Please close */
  switch (dl->state) {
    case DATALINK_OPEN:
      peerid_Init(&dl->peer);
      fsm2initial(&dl->physical->link.ccp.fsm);
      /* FALLTHROUGH */

    case DATALINK_CBCP:
    case DATALINK_AUTH:
    case DATALINK_LCP:
      datalink_AuthReInit(dl);
      if (how == CLOSE_LCP)
        datalink_DontHangup(dl);
      else if (how == CLOSE_STAYDOWN)
        datalink_StayDown(dl);
      fsm_Close(&dl->physical->link.lcp.fsm);
      break;

    default:
      datalink_ComeDown(dl, how);
  }
}
/*****************************************************************************
 函 数 名  : chap_Input
 功能描述  : 收到CHAP帧的处理入口函数
 输入参数  : l - PPP链接
             pstMem - 收到的CHAP帧
 输出参数  : 无
 返 回 值  : NULL
 调用函数  :
 被调函数  :

 修改历史      :
  1.日    期   : 2008年10月24日
    作    者   : liukai
    修改内容   : porting from BSD

*****************************************************************************/
PPP_ZC_STRU *chap_Input(struct link *l, PPP_ZC_STRU *pstMem)
{
    struct chap *chap;
    VOS_INT32 len;
    VOS_UCHAR alen;    /* answer length: challenge or response body length */
    struct ppp_mbuf *bp;
    VOS_UCHAR aucHashValue[MD5DIGESTSIZE];

    bp = ppp_m_get_from_ttfmem(pstMem);
    PPP_MemFree(pstMem);

    if (VOS_NULL_PTR == bp)
    {
        return VOS_NULL_PTR;
    }

    if (VOS_NULL_PTR == l) {
        PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_WARNING, "Chap Input: Not a physical link - dropped\r\n");
        ppp_m_freem(bp);
        return VOS_NULL_PTR;
    }

    if ((PHASE_NETWORK != l->phase) &&
            (PHASE_AUTHENTICATE != l->phase)) {
        PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "Unexpected Chap input - dropped\r\n");
        ppp_m_freem(bp);
        return VOS_NULL_PTR;
    }

    chap = &(l->chap);
    if ((VOS_NULL_PTR == (bp = auth_ReadHeader(&chap->auth, bp))) &&
            (0 == VOS_NTOHS(chap->auth.in.hdr.length)))
    {
        PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_WARNING, "Chap Input: Truncated header\r\n");
    }
    else if ((0 == chap->auth.in.hdr.code) || ((VOS_UINT8)(chap->auth.in.hdr.code) > MAXCHAPCODE))
    {
        PPP_MNTN_LOG1(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING,
                      "Chap Input: Bad CHAP code %d !\r\n", chap->auth.in.hdr.code);
    }
    else {
        len = ppp_m_length(bp);

        /* Identifier of rx-ed Response, Success, Fail should match Challenge tx-ed */
        if ((CHAP_CHALLENGE != chap->auth.in.hdr.code) &&
                (chap->auth.id != chap->auth.in.hdr.id)) {
            /* Wrong conversation dude ! */
            PPP_MNTN_LOG3(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL,
                          "Chap Input: code <1> dropped (got id <2> not equal to previous id <3>)\r\n",
                          chap->auth.in.hdr.code, chap->auth.in.hdr.id, chap->auth.id);
            ppp_m_freem(bp);
            return VOS_NULL_PTR;
        }
        chap->auth.id = chap->auth.in.hdr.id;    /* We respond with this id */

        if (CHAP_CHALLENGE == chap->auth.in.hdr.code)    /* rx-ed challenge */
        {
            bp = ppp_mbuf_Read(bp, &alen, 1);    /* fetch length of peer's challenge */
            len -= (alen + 1);    /* after this step, len is length of peer's name */
            if (len < 0) {
                PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING,
                              "Chap Input: Truncated challenge (len %d, alen %d)!\r\n", len, alen);
                ppp_m_freem(bp);
                return VOS_NULL_PTR;
            }
            if (AUTHLEN < len)
            {
                PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING,
                              "Chap Input: name of challenge too long (len %d, alen %d)!\r\n", len, alen);
                ppp_m_freem(bp);
                return VOS_NULL_PTR;
            }
            if (CHAPCHALLENGELEN < alen)
            {
                PPP_MNTN_LOG1(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING,
                              "Chap Input: challenge too long (len %d)!\r\n", alen);
                ppp_m_freem(bp);
                return VOS_NULL_PTR;
            }

            *chap->challenge.peer = alen;
            bp = ppp_mbuf_Read(bp, chap->challenge.peer + 1, alen);    /* record peer's challenge */
            bp = auth_ReadName(&chap->auth, bp, len);    /* record peer's name */

            if (*chap->auth.in.name)    /* challenge with name */
            {
                PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING,
                              "Chap Input: challenge (len %d, alen %d) with name\r\n",
                              len, alen);
            }
            else    /* without name */
            {
                PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING,
                              "Chap Input: challenge (len %d, alen %d) without name\r\n",
                              len, alen);
            }

            chap_Respond(l, "HUAWEI_CHAP_CLNT");    /* we always use "HUAWEI_CHAP_CLNT" as Name of Response */
        }    /* end of rx-ed challenge */
        else if (CHAP_RESPONSE == chap->auth.in.hdr.code)    /* rx-ed response */
        {
            bp = ppp_mbuf_Read(bp, &alen, 1);    /* read HASH-Size */
            if (MD5DIGESTSIZE != alen)    /* as just support MD5, must be 16 octets */
            {
                PPP_MNTN_LOG1(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING,
                              "Chap Input: Hash-Size %f is not correct !\r\n", alen);
                ppp_m_freem(bp);
                return VOS_NULL_PTR;
            }
            len -= (alen + 1);    /* after this step, len is length of Name Field */
            if (len < 0) {
                PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING,
                              "Chap Input: Truncated response (len %d, alen %d)!\r\n", len, alen);
                ppp_m_freem(bp);
                return VOS_NULL_PTR;
            }
            if (AUTHLEN < len)
            {
                PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING,
                              "Chap Input: name of response too long (len %d, alen %d)!\r\n", len, alen);
                ppp_m_freem(bp);
                return VOS_NULL_PTR;
            }

            bp = ppp_mbuf_Read(bp, aucHashValue, MD5DIGESTSIZE);    /* cut HASH value */
            bp = auth_ReadName(&chap->auth, bp, len);

            if (*chap->auth.in.name)
            {
                PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL,"Chap Input: response (len <1>, alen <2>) with name\r\n",
                              len, alen);
            }
            else
            {
                PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL,"Chap Input: response (len <1>, alen <2>) without name\r\n",
                              len, alen);
            }

            if (PHASE_AUTHENTICATE == l->phase)    /* 需要注意只备份在认证阶段中与challenge id匹配的response */
            {
                ChapBufferResponsePacket(chap, MD5DIGESTSIZE, aucHashValue, len);
            }

            chap_Success(l);

            /*
               Moves code to here as the last step of dealing with response by liukai,
               it should stop authentication timer after authentication pass or fail.
               Stops timer at first, a response frame format is not correct and discards it(way of BSD),
               UE has no chance to send challenge again
            */
            auth_StopTimer(&(chap->auth));
        }    /* end of rx-ed response */
        else if (CHAP_SUCCESS == chap->auth.in.hdr.code)    /* rx-ed success */
        {
            /* chap->auth.in.name is already set up at CHALLENGE time, need NOT to print again */
            if (0 < len)
            {
                PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "Chap Input: success with message\r\n");
            }
            else
            {
                PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "Chap Input: success without message\r\n");
            }

            if (PROTO_CHAP == l->lcp.auth_iwait) {
                l->lcp.auth_iwait = 0;
                if (0 == l->lcp.auth_ineed)    /* auth_ineed: 0, authentication by peer is not complete or no need to authentication,
                                                       !0, authentication by peer is complete */
                {
                    /*
                     * We've succeeded in our ``login''
                     * If we're not expecting  the peer to authenticate (or he already
                     * has), proceed to network phase.
                     */
                    chap_ReInit(&(l->chap));
                    if (PHASE_AUTHENTICATE == l->phase)
                    {
                        l->phase = PHASE_NETWORK;
                        l->ipcp.fsm.state = ST_CLOSED;
                        fsm_Open(&(l->ipcp.fsm));
                        PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "goto ipcp stage!\r\n");
                    }
                }
            }
        }    /* end of rx-ed success */
        else    /* rx-ed fail */
        {
            /* chap->auth.in.name is already set up at CHALLENGE time, need NOT to print again */
            if (0 < len)
            {
                PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "Chap Input: fail with message\r\n");
            }
            else
            {
                PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "Chap Input: fail without message\r\n");
            }

            chap_Cleanup(&(l->chap));
            l->phase = PHASE_TERMINATE;
            fsm_Close(&(l->lcp.fsm));
            PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "goto lcp stage!\r\n");
        }    /* end of rx-ed fail */
    }

    ppp_m_freem(bp);
    return VOS_NULL_PTR;
}    /* chap_Input */
Exemplo n.º 5
0
static void
ipv6cp_DecodeConfig(struct fsm *fp, u_char *cp, u_char *end, int mode_type,
                    struct fsm_decode *dec)
{
  /* Deal with incoming PROTO_IPV6CP */
  struct ipv6cp *ipv6cp = fsm2ipv6cp(fp);
  int n;
  char tbuff[100];
  u_char ifid[IPV6CP_IFIDLEN], zero[IPV6CP_IFIDLEN];
  struct fsm_opt *opt;

  memset(zero, 0, IPV6CP_IFIDLEN);

  while (end - cp >= (int)sizeof(opt->hdr)) {
    if ((opt = fsm_readopt(&cp)) == NULL)
      break;

    snprintf(tbuff, sizeof tbuff, " %s[%d]", protoname(opt->hdr.id),
             opt->hdr.len);

    switch (opt->hdr.id) {
    case TY_TOKEN:
      memcpy(ifid, opt->data, IPV6CP_IFIDLEN);
      log_Printf(LogIPV6CP, "%s 0x%02x%02x%02x%02x%02x%02x%02x%02x\n", tbuff,
		 ifid[0], ifid[1], ifid[2], ifid[3], ifid[4], ifid[5], ifid[6], ifid[7]);

      switch (mode_type) {
      case MODE_REQ:
        ipv6cp->peer_tokenreq = 1;
        ipv6cp_ValidateInterfaceID(ipv6cp, ifid, dec);
        break;

      case MODE_NAK:
        if (memcmp(ifid, zero, IPV6CP_IFIDLEN) == 0) {
          log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE,
		     "0x0000000000000000: Unacceptable IntefaceID!\n");
          fsm_Close(&ipv6cp->fsm);
        } else if (memcmp(ifid, ipv6cp->his_ifid, IPV6CP_IFIDLEN) == 0) {
          log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE,
		     "0x%02x%02x%02x%02x%02x%02x%02x%02x: "
		     "Unacceptable IntefaceID!\n",
		     ifid[0], ifid[1], ifid[2], ifid[3],
		     ifid[4], ifid[5], ifid[6], ifid[7]);
        } else if (memcmp(ifid, ipv6cp->my_ifid, IPV6CP_IFIDLEN) != 0) {
          n = 100;
	  while (n && !ipcp_SetIPv6address(ipv6cp, ifid, ipv6cp->his_ifid)) {
	    do {
	      n--;
	      SetInterfaceID(ifid, 1);
	    } while (n && memcmp(ifid, ipv6cp->his_ifid, IPV6CP_IFIDLEN) == 0);
	  }

          if (n == 0) {
            log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE,
                       "0x0000000000000000: Unacceptable IntefaceID!\n");
            fsm_Close(&ipv6cp->fsm);
          } else {
	    log_Printf(LogIPV6CP, "%s changing IntefaceID: "
		       "0x%02x%02x%02x%02x%02x%02x%02x%02x "
		       "--> 0x%02x%02x%02x%02x%02x%02x%02x%02x\n", tbuff,
		       ipv6cp->my_ifid[0], ipv6cp->my_ifid[1],
		       ipv6cp->my_ifid[2], ipv6cp->my_ifid[3],
		       ipv6cp->my_ifid[4], ipv6cp->my_ifid[5],
		       ipv6cp->my_ifid[6], ipv6cp->my_ifid[7],
		       ifid[0], ifid[1], ifid[2], ifid[3],
		       ifid[4], ifid[5], ifid[6], ifid[7]);
            memcpy(ipv6cp->my_ifid, ifid, IPV6CP_IFIDLEN);
            bundle_AdjustFilters(fp->bundle, &ipv6cp->myaddr, NULL);
          }
        }
        break;

      case MODE_REJ:
        ipv6cp->his_reject |= (1 << opt->hdr.id);
        break;
      }
      break;

    default:
      if (mode_type != MODE_NOP) {
        ipv6cp->my_reject |= (1 << opt->hdr.id);
        fsm_rej(dec, opt);
      }
      break;
    }
  }

  if (mode_type != MODE_NOP) {
    if (mode_type == MODE_REQ && !ipv6cp->peer_tokenreq) {
      if (dec->rejend == dec->rej && dec->nakend == dec->nak) {
        /*
         * Pretend the peer has requested a TOKEN.
         * We do this to ensure that we only send one NAK if the only
         * reason for the NAK is because the peer isn't sending a
         * TY_TOKEN REQ.  This stops us from repeatedly trying to tell
         * the peer that we have to have an IP address on their end.
         */
        ipv6cp->peer_tokenreq = 1;
      }
      memset(ifid, 0, IPV6CP_IFIDLEN);
      ipv6cp_ValidateInterfaceID(ipv6cp, ifid, dec);
    }
    fsm_opt_normalise(dec);
  }
}
Exemplo n.º 6
0
/*****************************************************************************
 Prototype      : Ppp_ReleasePppReq
 Description    : 为AT模块"释放PPP链路"提供对应的API函数。

 Input          : ---要释放的PPP链路对应的PPP ID
 Output         : ---
 Return Value   : ---VOS_UINT32
 Calls          : ---
 Called By      : ---

 History        : ---
  1.Date        : 2005-11-18
    Author      : ---
    Modification: Created function
*****************************************************************************/
VOS_UINT32 Ppp_ReleasePppReq ( PPP_ID usPppId)
{
    VOS_UINT32                          ulRet;


    /* 可维可测信息上报*/
    Ppp_EventMntnInfo(usPppId, AT_PPP_RELEASE_PPP_REQ);

    if(VOS_OK != PppIsIdValid(usPppId))
    {
        return VOS_ERR;
    }

    /* 如果当前PPP在PHASE_NETWORK阶段,属于网侧主动去激活
       此时PPP等待和PC间PPP协议结束后通知AT拉管脚信号,并起定时器保护*/
    if (PHASE_NETWORK == (PPP_LINK(usPppId)->phase))
    {
        if (VOS_NULL_PTR != (PPP_LINK(usPppId)->lcp.hLcpCloseTimer))
        {
            PS_STOP_REL_TIMER(&(PPP_LINK(usPppId)->lcp.hLcpCloseTimer));
            PPP_LINK(usPppId)->lcp.hLcpCloseTimer= VOS_NULL_PTR;
        }

        /*起定时器,确保通知拉AT管脚信号*/
        ulRet = VOS_StartRelTimer(&(PPP_LINK(usPppId)->lcp.hLcpCloseTimer),  PS_PID_APP_PPP,
            1000,  usPppId,  PHASE_TERMINATE_PENDING,  VOS_RELTIMER_NOLOOP,  VOS_TIMER_PRECISION_5 );

        if (VOS_OK != ulRet)
        {
            PPP_LINK(usPppId)->lcp.hLcpCloseTimer = VOS_NULL_PTR;
            PPP_ProcPppDisconnEvent(usPppId);
        }
    }

    /*首先调用PPP模块对应的函数*/
    fsm_Close(&(PPP_LINK(usPppId)->ipcp.fsm));
    fsm_Close(&(PPP_LINK(usPppId)->lcp.fsm));

    /*停止IPCP状态机定时器:*/
    if( VOS_NULL_PTR !=((PPP_LINK(usPppId))->ipcp.fsm.timer) )
    {
        VOS_StopRelTimer(&((PPP_LINK(usPppId))->ipcp.fsm.timer));
        (PPP_LINK(usPppId))->ipcp.fsm.timer = VOS_NULL_PTR;
    }

    /*停止CHAP状态机定时器:*/
    if( VOS_NULL_PTR !=((PPP_LINK(usPppId))->chap.auth.hAuthTimer) )
    {
        VOS_StopRelTimer(&((PPP_LINK(usPppId))->chap.auth.hAuthTimer));
        (PPP_LINK(usPppId))->chap.auth.hAuthTimer = VOS_NULL_PTR;
    }

    /*停止LCP状态机定时器:*/
    if( VOS_NULL_PTR !=((PPP_LINK(usPppId))->lcp.fsm.timer) )
    {
        VOS_StopRelTimer(&((PPP_LINK(usPppId))->lcp.fsm.timer));
        (PPP_LINK(usPppId))->lcp.fsm.timer = VOS_NULL_PTR;
    }

    /*释放待PDP激活定时器*/
    if (VOS_NULL_PTR != (PPP_LINK(usPppId)->ipcp.hIpcpPendTimer))
    {
        PS_STOP_REL_TIMER(&(PPP_LINK(usPppId)->ipcp.hIpcpPendTimer));
        PPP_LINK(usPppId)->ipcp.hIpcpPendTimer = VOS_NULL_PTR;
    }

    /*释放待处理IPCP帧*/
    if (VOS_NULL_PTR != (PPP_LINK(usPppId)->ipcp.pstIpcpPendFrame))
    {
        ppp_m_freem(PPP_LINK(usPppId)->ipcp.pstIpcpPendFrame);
        PPP_LINK(usPppId)->ipcp.pstIpcpPendFrame = VOS_NULL_PTR;
    }

    PppFreeId(usPppId);

    /* 不用释放PPP数据队列,因为只要队列里面有数据,PPP任务就会被调度起来处理,
       如果HDLC处理完成而PPP实体已经释放,那么封装或解封装出来的数据自然会被丢弃。
       这个API会在AT任务里被调用,如果这里把数据放掉,PPP任务有可能正在使用 */
    /* PPP_ClearDataQ(); */

    /*返回正确*/
    return VOS_OK;
}
Exemplo n.º 7
0
static void
CcpDecodeConfig(struct fsm *fp, u_char *cp, u_char *end, int mode_type,
                struct fsm_decode *dec)
{
  /* Deal with incoming data */
  struct ccp *ccp = fsm2ccp(fp);
  int f;
  const char *disp;
  struct fsm_opt *opt;

  if (mode_type == MODE_REQ)
    ccp->in.algorithm = -1;	/* In case we've received two REQs in a row */

  while (end >= cp + sizeof(opt->hdr)) {
    if ((opt = fsm_readopt(&cp)) == NULL)
      break;

    for (f = NALGORITHMS-1; f > -1; f--)
      if (algorithm[f]->id == opt->hdr.id)
        break;

    disp = f == -1 ? "" : (*algorithm[f]->Disp)(opt);
    if (disp == NULL)
      disp = "";

    log_Printf(LogCCP, " %s[%d] %s\n", protoname(opt->hdr.id),
               opt->hdr.len, disp);

    if (f == -1) {
      /* Don't understand that :-( */
      if (mode_type == MODE_REQ) {
        ccp->my_reject |= (1 << opt->hdr.id);
        fsm_rej(dec, opt);
      }
    } else {
      struct ccp_opt *o;

      switch (mode_type) {
      case MODE_REQ:
        if (IsAccepted(ccp->cfg.neg[algorithm[f]->Neg]) &&
            (*algorithm[f]->Usable)(fp) &&
            ccp->in.algorithm == -1) {
          memcpy(&ccp->in.opt, opt, opt->hdr.len);
          switch ((*algorithm[f]->i.Set)(fp->bundle, &ccp->in.opt, &ccp->cfg)) {
          case MODE_REJ:
            fsm_rej(dec, &ccp->in.opt);
            break;
          case MODE_NAK:
            fsm_nak(dec, &ccp->in.opt);
            break;
          case MODE_ACK:
            fsm_ack(dec, &ccp->in.opt);
            ccp->his_proto = opt->hdr.id;
            ccp->in.algorithm = (int)f;		/* This one'll do :-) */
            break;
          }
        } else {
          fsm_rej(dec, opt);
        }
        break;
      case MODE_NAK:
        for (o = ccp->out.opt; o != NULL; o = o->next)
          if (o->val.hdr.id == opt->hdr.id)
            break;
        if (o == NULL)
          log_Printf(LogCCP, "%s: Warning: Ignoring peer NAK of unsent"
                     " option\n", fp->link->name);
        else {
          memcpy(&o->val, opt, opt->hdr.len);
          if ((*algorithm[f]->o.Set)(fp->bundle, &o->val, &ccp->cfg) ==
              MODE_ACK)
            ccp->my_proto = algorithm[f]->id;
          else {
            ccp->his_reject |= (1 << opt->hdr.id);
            ccp->my_proto = -1;
            if (algorithm[f]->Required(fp)) {
              log_Printf(LogWARN, "%s: Cannot understand peers (required)"
                         " %s negotiation\n", fp->link->name,
                         protoname(algorithm[f]->id));
              fsm_Close(&fp->link->lcp.fsm);
            }
          }
        }
        break;
      case MODE_REJ:
        ccp->his_reject |= (1 << opt->hdr.id);
        ccp->my_proto = -1;
        if (algorithm[f]->Required(fp)) {
          log_Printf(LogWARN, "%s: Peer rejected (required) %s negotiation\n",
                     fp->link->name, protoname(algorithm[f]->id));
          fsm_Close(&fp->link->lcp.fsm);
        }
        break;
      }
    }
  }

  if (mode_type != MODE_NOP) {
    fsm_opt_normalise(dec);
    if (dec->rejend != dec->rej || dec->nakend != dec->nak) {
      if (ccp->in.state == NULL) {
        ccp->his_proto = -1;
        ccp->in.algorithm = -1;
      }
    }
  }
}
Exemplo n.º 8
0
/*  Called when CCP has reached the OPEN state */
static int
CcpLayerUp(struct fsm *fp)
{
  /* We're now up */
  struct ccp *ccp = fsm2ccp(fp);
  struct ccp_opt **o;
  unsigned f, fail;

  for (f = fail = 0; f < NALGORITHMS; f++)
    if (IsEnabled(ccp->cfg.neg[algorithm[f]->Neg]) &&
        (*algorithm[f]->Required)(&ccp->fsm) &&
        (ccp->in.algorithm != (int)f || ccp->out.algorithm != (int)f)) {
      /* Blow it all away - we haven't negotiated a required algorithm */
      log_Printf(LogWARN, "%s: Failed to negotiate (required) %s\n",
                 fp->link->name, protoname(algorithm[f]->id));
      fail = 1;
    }

  if (fail) {
    ccp->his_proto = ccp->my_proto = -1;
    fsm_Close(fp);
    fsm_Close(&fp->link->lcp.fsm);
    return 0;
  }

  log_Printf(LogCCP, "%s: LayerUp.\n", fp->link->name);

  if (ccp->in.state == NULL && ccp->in.algorithm >= 0 &&
      ccp->in.algorithm < (int)NALGORITHMS) {
    ccp->in.state = (*algorithm[ccp->in.algorithm]->i.Init)
      (fp->bundle, &ccp->in.opt);
    if (ccp->in.state == NULL) {
      log_Printf(LogERROR, "%s: %s (in) initialisation failure\n",
                fp->link->name, protoname(ccp->his_proto));
      ccp->his_proto = ccp->my_proto = -1;
      fsm_Close(fp);
      return 0;
    }
  }

  o = &ccp->out.opt;
  if (ccp->out.algorithm > 0)
    for (f = 0; f < (unsigned)ccp->out.algorithm; f++)
      if (IsEnabled(ccp->cfg.neg[algorithm[f]->Neg]))
	o = &(*o)->next;

  if (ccp->out.state == NULL && ccp->out.algorithm >= 0 &&
      ccp->out.algorithm < (int)NALGORITHMS) {
    ccp->out.state = (*algorithm[ccp->out.algorithm]->o.Init)
      (fp->bundle, &(*o)->val);
    if (ccp->out.state == NULL) {
      log_Printf(LogERROR, "%s: %s (out) initialisation failure\n",
                fp->link->name, protoname(ccp->my_proto));
      ccp->his_proto = ccp->my_proto = -1;
      fsm_Close(fp);
      return 0;
    }
  }

  fp->more.reqs = fp->more.naks = fp->more.rejs = ccp->cfg.fsm.maxreq * 3;

  log_Printf(LogCCP, "%s: Out = %s[%d], In = %s[%d]\n",
            fp->link->name, protoname(ccp->my_proto), ccp->my_proto,
            protoname(ccp->his_proto), ccp->his_proto);

  return 1;
}
Exemplo n.º 9
0
void
datalink_AuthOk(struct datalink *dl)
{
  if ((dl->physical->link.lcp.his_callback.opmask &
       CALLBACK_BIT(CALLBACK_CBCP) ||
       dl->physical->link.lcp.want_callback.opmask &
       CALLBACK_BIT(CALLBACK_CBCP)) &&
      !(dl->physical->link.lcp.want_callback.opmask &
        CALLBACK_BIT(CALLBACK_AUTH))) {
    /* We must have agreed CBCP if AUTH isn't there any more */
    datalink_NewState(dl, DATALINK_CBCP);
    cbcp_Up(&dl->cbcp);
  } else if (dl->physical->link.lcp.want_callback.opmask) {
    /* It's not CBCP */
    log_Printf(LogPHASE, "%s: Shutdown and await peer callback\n", dl->name);
    datalink_NewState(dl, DATALINK_LCP);
    datalink_AuthReInit(dl);
    fsm_Close(&dl->physical->link.lcp.fsm);
  } else
    switch (dl->physical->link.lcp.his_callback.opmask) {
      case 0:
        datalink_NCPUp(dl);
        break;

      case CALLBACK_BIT(CALLBACK_AUTH):
        auth_SetPhoneList(dl->peer.authname, dl->cbcp.fsm.phone,
                          sizeof dl->cbcp.fsm.phone);
        if (*dl->cbcp.fsm.phone == '\0' || !strcmp(dl->cbcp.fsm.phone, "*")) {
          log_Printf(LogPHASE, "%s: %s cannot be called back\n", dl->name,
                     dl->peer.authname);
          *dl->cbcp.fsm.phone = '\0';
        } else {
          char *ptr = strchr(dl->cbcp.fsm.phone, ',');
          if (ptr)
            *ptr = '\0';	/* Call back on the first number */
          log_Printf(LogPHASE, "%s: Calling peer back on %s\n", dl->name,
                     dl->cbcp.fsm.phone);
          dl->cbcp.required = 1;
        }
        dl->cbcp.fsm.delay = 0;
        datalink_NewState(dl, DATALINK_LCP);
        datalink_AuthReInit(dl);
        fsm_Close(&dl->physical->link.lcp.fsm);
        break;

      case CALLBACK_BIT(CALLBACK_E164):
        strncpy(dl->cbcp.fsm.phone, dl->physical->link.lcp.his_callback.msg,
                sizeof dl->cbcp.fsm.phone - 1);
        dl->cbcp.fsm.phone[sizeof dl->cbcp.fsm.phone - 1] = '\0';
        log_Printf(LogPHASE, "%s: Calling peer back on %s\n", dl->name,
                   dl->cbcp.fsm.phone);
        dl->cbcp.required = 1;
        dl->cbcp.fsm.delay = 0;
        datalink_NewState(dl, DATALINK_LCP);
        datalink_AuthReInit(dl);
        fsm_Close(&dl->physical->link.lcp.fsm);
        break;

      default:
        log_Printf(LogPHASE, "%s: Oops - Should have NAK'd peer callback !\n",
                   dl->name);
        datalink_NewState(dl, DATALINK_LCP);
        datalink_AuthReInit(dl);
        fsm_Close(&dl->physical->link.lcp.fsm);
        break;
    }
}