/***************************************************************************** 函 数 名 : chap_Success 功能描述 : 构造Success帧并发送 输入参数 : l - PPP链接 输出参数 : 无 返 回 值 : 无 调用函数 : 被调函数 : 修改历史 : 1.日 期 : 2008年10月25日 作 者 : liukai 修改内容 : porting from BSD *****************************************************************************/ static VOS_VOID chap_Success(struct link *l) { struct authinfo *authp = &(l->chap.auth); const VOS_CHAR *pcMsg = "Welcome!!"; /* follow BSD use "Welcome!!" as message */ /* Success body: */ /* * ------------- * | Message | * ------------- */ ChapOutput(l, CHAP_SUCCESS, authp->id, (VOS_UCHAR *)pcMsg, VOS_StrLen((VOS_CHAR *)pcMsg), VOS_NULL_PTR); l->lcp.auth_ineed = 0; /* after Authentication, clear flag to authenticate peer */ if (0 == l->lcp.auth_iwait) /* auth_iwait: 0, authentication to peer is not complete or no need to authentication, !0, authentication to peer is complete */ { /* * Either I didn't need to authenticate, or I've already been * told that I got the answer right. */ 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"); } } return; } /* chap_Success */
static void datalink_LayerFinish(void *v, struct fsm *fp) { /* The given fsm is now down */ struct datalink *dl = (struct datalink *)v; if (fp->proto == PROTO_LCP) { fsm2initial(fp); (*dl->parent->LayerFinish)(dl->parent->object, fp); datalink_ComeDown(dl, CLOSE_NORMAL); } else if (fp->state == ST_CLOSED && fp->open_mode == OPEN_PASSIVE) fsm_Open(fp); /* CCP goes to ST_STOPPED */ }
int ncp_fsmStart(struct ncp *ncp, struct bundle *bundle) { int res = 0; #ifndef NOINET6 if (Enabled(bundle, OPT_IPCP)) { #endif fsm_Up(&ncp->ipcp.fsm); fsm_Open(&ncp->ipcp.fsm); res++; #ifndef NOINET6 } if (Enabled(bundle, OPT_IPV6CP)) { fsm_Up(&ncp->ipv6cp.fsm); fsm_Open(&ncp->ipv6cp.fsm); res++; } #endif return res; }
void datalink_NCPUp(struct datalink *dl) { int ccpok = ccp_SetOpenMode(&dl->physical->link.ccp); if (dl->physical->link.lcp.want_mrru && dl->physical->link.lcp.his_mrru) { /* we've authenticated in multilink mode ! */ switch (mp_Up(&dl->bundle->ncp.mp, dl)) { case MP_LINKSENT: /* We've handed the link off to another ppp (well, we will soon) ! */ return; case MP_UP: /* First link in the bundle */ auth_Select(dl->bundle, dl->peer.authname); bundle_CalculateBandwidth(dl->bundle); /* FALLTHROUGH */ case MP_ADDED: /* We're in multilink mode ! */ dl->physical->link.ccp.fsm.open_mode = OPEN_PASSIVE; /* override */ bundle_CalculateBandwidth(dl->bundle); break; case MP_FAILED: datalink_AuthNotOk(dl); return; } } else if (bundle_Phase(dl->bundle) == PHASE_NETWORK) { log_Printf(LogPHASE, "%s: Already in NETWORK phase\n", dl->name); datalink_NewState(dl, DATALINK_OPEN); bundle_CalculateBandwidth(dl->bundle); (*dl->parent->LayerUp)(dl->parent->object, &dl->physical->link.lcp.fsm); return; } else { dl->bundle->ncp.mp.peer = dl->peer; ncp_SetLink(&dl->bundle->ncp, &dl->physical->link); auth_Select(dl->bundle, dl->peer.authname); } if (ccpok) { fsm_Up(&dl->physical->link.ccp.fsm); fsm_Open(&dl->physical->link.ccp.fsm); } datalink_NewState(dl, DATALINK_OPEN); bundle_NewPhase(dl->bundle, PHASE_NETWORK); (*dl->parent->LayerUp)(dl->parent->object, &dl->physical->link.lcp.fsm); }
void pap_Success(struct link *l) { #if 0/*fanzhibin f49086 delete it*/ struct bundle *bundle = authp->physical->dl->bundle; datalink_GotAuthname(authp->physical->dl, authp->in.name); #ifndef NORADIUS if (*bundle->radius.cfg.file && bundle->radius.repstr) SendPapCode(authp, PAP_ACK, bundle->radius.repstr); else #endif #endif SendPapCode(l, PAP_ACK, "Greetings!!"); #if 0/*fanzhibin f49086 delete it*/ /*下面这句在改造的时候要添进去*/ authp->physical->link.lcp.auth_ineed = 0; if (Enabled(bundle, OPT_UTMP)) physical_Login(authp->physical, authp->in.name); /*下面这句在改造的时候要添进去*/ if (authp->physical->link.lcp.auth_iwait == 0) /* * Either I didn't need to authenticate, or I've already been * told that I got the answer right. */ datalink_AuthOk(authp->physical->dl); #endif /*fanzhibin f49086 add it begin*/ l->lcp.auth_ineed = 0; if(l->lcp.auth_iwait == 0) /* auth_iwait: 0, authentication to peer is not complete or no need to authentication, !0, authentication to peer is complete */ { 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"); } } /*fanzhibin f49086 add it end*/ }
/***************************************************************************** Prototype : Ppp_CreatePppReq Description : 为AT模块"创建PPP链路"提供对应的API函数。 Input : --- Output : ---创建成功后返回的PPP ID Return Value : ---VOS_UINT32 Calls : --- Called By : --- History : --- 1.Date : 2005-11-18 Author : --- Modification: Created function *****************************************************************************/ VOS_UINT32 Ppp_CreatePppReq ( PPP_ID *pusPppId) { PPP_ID pppid_get; if(pusPppId == VOS_NULL) { return VOS_ERR; } /*从PPP ID数组中得到一个空闲的PPP ID*/ pppid_get = PppGetId(); /*如果没有空闲的PPP ID*/ if(pppid_get == 0) { return VOS_ERR; } /*如果有空闲的PPP ID,首先将申请得到的PPP ID赋值给AT_CMD*/ *pusPppId = pppid_get; /*然后调用PPP模块对应的函数*/ link_Init(PPP_LINK(pppid_get)); PPP_LINK(pppid_get)->phase = PHASE_ESTABLISH; PPP_LINK(pppid_get)->lcp.fsm.state = ST_CLOSED; fsm_Open(&(PPP_LINK(pppid_get)->lcp.fsm)); /*释放PPP数据队列*/ PPP_ClearDataQ(); /* 初始化HDLC相关配置 */ PPP_InitHdlcConfig(pppid_get); /* 可维可测信息上报*/ Ppp_EventMntnInfo(pppid_get, AT_PPP_CREATE_PPP_REQ); /*返回正确*/ return VOS_OK; }
static void datalink_LoginDone(struct datalink *dl) { chat_Finish(&dl->chat); if (!dl->script.packetmode) { dl->dial.tries = -1; dl->dial.incs = 0; datalink_NewState(dl, DATALINK_READY); } else if (!physical_Raw(dl->physical)) { dl->dial.tries = 0; log_Printf(LogWARN, "datalink_LoginDone: Not connected.\n"); if (dl->script.run) { datalink_NewState(dl, DATALINK_LOGOUT); if (!chat_Setup(&dl->chat, dl->cfg.script.logout, NULL)) log_Printf(LogWARN, "Invalid logout script\n"); } else { physical_StopDeviceTimer(dl->physical); if (dl->physical->type == PHYS_DEDICATED) /* force a redial timeout */ physical_Close(dl->physical); datalink_HangupDone(dl); } } else { dl->dial.tries = -1; dl->dial.incs = 0; hdlc_Init(&dl->physical->hdlc, &dl->physical->link.lcp); async_Setup(&dl->physical->async); lcp_Setup(&dl->physical->link.lcp, dl->state == DATALINK_READY ? 0 : dl->physical->link.lcp.cfg.openmode); ccp_Setup(&dl->physical->link.ccp); datalink_NewState(dl, DATALINK_LCP); fsm_Up(&dl->physical->link.lcp.fsm); fsm_Open(&dl->physical->link.lcp.fsm); } }
/***************************************************************************** 函 数 名 : 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 */