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); } }
void datalink_AuthNotOk(struct datalink *dl) { datalink_NewState(dl, DATALINK_LCP); datalink_AuthReInit(dl); fsm_Close(&dl->physical->link.lcp.fsm); }
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 */
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); } }
/***************************************************************************** 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; }
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; } } } }
/* 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; }
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; } }