/***************************************************************************** Prototype : Ppp_RcvConfigInfoInd Description : 为AT模块"PPP模块接收网侧指示的配置信息"提供对应的API函数。 当AT向GGSN认证成功后,调用此函数向PPP发指示。 Input : usPppId---要发指示的PPP链路所在的PPP ID pPppIndConfigInfo---从GGSN发来的该PPP链路的IP地址等信息 Output : --- Return Value : ---VOS_UINT32 Calls : --- Called By : --- History : --- 1.Date : 2005-11-18 Author : --- Modification: Created function *****************************************************************************/ VOS_UINT32 Ppp_RcvConfigInfoInd ( PPP_ID usPppId, AT_PPP_IND_CONFIG_INFO_STRU *pstAtPppIndConfigInfo ) { VOS_UINT8 ucRabId; VOS_UINT32 ulResult; if(VOS_OK != PppIsIdValid(usPppId)) { PPP_MNTN_LOG1(PS_PID_APP_PPP, 0, PS_PRINT_WARNING, "PPP, Ppp_RcvConfigInfoInd, WARNING, Invalid PPP Id %d", usPppId); return VOS_ERR; } /* 通过usPppId,寻找到usRabId */ if ( !PPP_PPPID_TO_RAB(usPppId, &ucRabId) ) { PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "PPP, Ppp_RcvConfigInfoInd, WARNING, Can not get PPP Id %d, RabId %d", usPppId, ucRabId); return VOS_ERR; } /* 这个时候PDP已经激活,注册上行数据接收接口。另外当前不支持PPP类型拨号。 */ ulResult= ADS_DL_RegDlDataCallback(ucRabId, (RCV_DL_DATA_FUNC)PPP_PushPacketEvent); if ( VOS_OK != ulResult ) { PPP_MNTN_LOG1(PS_PID_APP_PPP, 0, PS_PRINT_WARNING, "PPP, Ppp_RcvConfigInfoInd, WARNING, Register DL CB failed! RabId %d", ucRabId); return VOS_ERR; } /* 保存PCO信息 */ PPP_SavePcoInfo(usPppId, pstAtPppIndConfigInfo); Ppp_RcvConfigInfoIndMntnInfo(usPppId, pstAtPppIndConfigInfo); PPP_RcvAtCtrlOperEvent(usPppId, PPP_AT_CTRL_CONFIG_INFO_IND); /*返回正确*/ return VOS_OK; }
/*lint -e958*/ struct ppp_mbuf * link_Dequeue(struct link *l) { VOS_INT32 pri; struct ppp_mbuf *bp; for (bp = VOS_NULL_PTR, pri = LINK_QUEUES(l) - 1; pri >= 0; pri--) { if (l->Queue[pri].len) { bp = ppp_m_dequeue(l->Queue + pri); PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "pri <1>;length <2>\r\n", pri, (VOS_INT32)l->Queue[pri].len); break; } } return bp; }
/***************************************************************************** 函 数 名 : PPP_SendPulledData 功能描述 : 上行发送数据给协议栈 输入参数 : ucPppId --- PPP ID pstMem --- TTF_MEM形式的数据 输出参数 : 返 回 值 : PS_SUCC 成功;PS_FAIL 失败 调用函数 : 被调函数 : 修改历史 : 1.日 期 : 2011-03-09 作 者 : l00164359 修改内容 : Created *****************************************************************************/ VOS_UINT32 PPP_SendPulledData(VOS_UINT16 usPppId, PPP_ZC_STRU *pstImmZc) { VOS_UINT8 ucRabId = PPP_INVALID_RABID; VOS_UINT32 ulResult; /*Add by y45445*/ #ifdef WTTF_PS_FUSION_PC_ST ucRabId = 5; #else /* 通过usPppId,寻找到usRabId */ if ( !PPP_PPPID_TO_RAB(usPppId, &ucRabId) ) { g_PppDataQCtrl.stStat.ulUplinkDropCnt++; PPP_MemFree(pstImmZc); PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "PPP, PPP_PushPacketEvent, WARNING, Can not get PPP Id %d, RabId %d", usPppId, ucRabId); return PS_FAIL; } #endif /*Add by y45445*/ /* 数据发送给ADS,如果失败则释放内存 */ ulResult = ADS_UL_SendPacket(pstImmZc, ucRabId); if ( VOS_OK != ulResult ) { g_PppDataQCtrl.stStat.ulUplinkDropCnt++; PPP_MemFree(pstImmZc); return PS_FAIL; } g_PppDataQCtrl.stStat.ulUplinkSndDataCnt++; return PS_SUCC; }
/***************************************************************************** Prototype : Ppp_RegDlDataCallback Description : 为AT模块提供注册下行发送数据的API Input : usPppId---要发指示的PPP链路所在的PPP ID Output : --- Return Value : ---VOS_UINT32 Calls : --- Called By : --- History : --- 1.Date : 2013-06-04 Author : --- Modification: Created function *****************************************************************************/ VOS_UINT32 Ppp_RegDlDataCallback(PPP_ID usPppId) { VOS_UINT8 ucRabId; VOS_UINT32 ulResult; if(VOS_OK != PppIsIdValid(usPppId)) { PPP_MNTN_LOG1(PS_PID_APP_PPP, 0, PS_PRINT_WARNING, "PPP, Ppp_RegDlDataCallback, WARNING, Invalid PPP Id %d", usPppId); return VOS_ERR; } /* 通过usPppId,寻找到usRabId */ if (!PPP_PPPID_TO_RAB(usPppId, &ucRabId)) { PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "PPP, Ppp_RegDlDataCallback, WARNING, Can not get PPP Id %d, RabId %d", usPppId, ucRabId); return VOS_ERR; } /* 这个时候PDP已经激活,注册上行数据接收接口 */ ulResult= ADS_DL_RegDlDataCallback(ucRabId, (RCV_DL_DATA_FUNC)PPP_PushRawDataEvent); if ( VOS_OK != ulResult ) { PPP_MNTN_LOG1(PS_PID_APP_PPP, 0, PS_PRINT_WARNING, "PPP, Ppp_RegDlDataCallback, WARNING, Register DL CB failed! RabId %d", ucRabId); return VOS_ERR; } return VOS_OK; }
/***************************************************************************** 函 数 名 : 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 */
VOS_UINT32 PPP_SavePcoInfo ( PPP_ID usPppId, AT_PPP_IND_CONFIG_INFO_STRU *pstAtPppIndConfigInfo ) { struct ipcp *pstIpcp; AT_PPP_PCO_IPV4_ITEM_STRU *pstPcoIpv4Item; pstIpcp = &(PPP_LINK(usPppId)->ipcp); pstPcoIpv4Item = &(pstAtPppIndConfigInfo->stPcoIpv4Item); PPP_MNTN_LOG1(PS_PID_APP_PPP, 0, PS_PRINT_INFO, "PPP_SavePcoInfo, aucIpAddr %d\r\n", (VOS_INT)pstAtPppIndConfigInfo->aucIpAddr); PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, PS_PRINT_INFO, "PPP_SavePcoInfo, bitOpPriDns %d, aucPriDns %d\r\n", (VOS_INT)pstPcoIpv4Item->bitOpPriDns, (VOS_INT)pstPcoIpv4Item->aucPriDns); PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, PS_PRINT_INFO, "PPP_SavePcoInfo, bitOpSecDns %d, aucSecDns %d\r\n", (VOS_INT)pstPcoIpv4Item->bitOpSecDns, (VOS_INT)pstPcoIpv4Item->aucSecDns); PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, PS_PRINT_INFO, "PPP_SavePcoInfo, bitOpPriNbns %d, aucPriNbns %d\r\n", (VOS_INT)pstPcoIpv4Item->bitOpPriNbns, (VOS_INT)pstPcoIpv4Item->aucPriNbns); PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, PS_PRINT_INFO, "PPP_SavePcoInfo, bitOpSecNbns %d, aucSecNbns %d\r\n", (VOS_INT)pstPcoIpv4Item->bitOpSecNbns, (VOS_INT)pstPcoIpv4Item->aucSecNbns); /* 保存主DNS服务器地址 */ if ( pstPcoIpv4Item->bitOpPriDns ) { PS_MEM_CPY(&(pstIpcp->PriDnsAddr.s_addr), pstPcoIpv4Item->aucPriDns, IPV4_ADDR_LEN); pstIpcp->PriDns_neg |= NEG_ACCEPTED; } /* 保存辅DNS服务器地址 */ if ( pstPcoIpv4Item->bitOpSecDns ) { PS_MEM_CPY(&(pstIpcp->SecDnsAddr.s_addr), pstPcoIpv4Item->aucSecDns, IPV4_ADDR_LEN); pstIpcp->SecDns_neg |= NEG_ACCEPTED; } /* 保存主NBNS服务器地址 */ if ( (pstPcoIpv4Item->bitOpPriNbns) && (WINS_CONFIG_ENABLE == g_ucPppConfigWins)) { PS_MEM_CPY(&(pstIpcp->PriNbnsAddr.s_addr), pstPcoIpv4Item->aucPriNbns, IPV4_ADDR_LEN); pstIpcp->PriNbns_neg |= NEG_ACCEPTED; } /* 保存辅NBNS服务器地址 */ if ( (pstPcoIpv4Item->bitOpSecNbns) && (WINS_CONFIG_ENABLE == g_ucPppConfigWins)) { PS_MEM_CPY(&(pstIpcp->SecNbnsAddr.s_addr), pstPcoIpv4Item->aucSecNbns, IPV4_ADDR_LEN); pstIpcp->SecNbns_neg |= NEG_ACCEPTED; } /* 参考Ppp_RcvConfigInfoInd实现,peer_ip填主机地址aucIpAddr */ PS_MEM_CPY(&(pstIpcp->peer_ip.s_addr), pstAtPppIndConfigInfo->aucIpAddr, IPV4_ADDR_LEN); pstIpcp->IpAddr_neg |= NEG_ACCEPTED; /* 切换IPCP协商状态 */ if(pstIpcp->stage == IPCP_REQ_RECEIVED) { pstIpcp->stage = IPCP_SUCCESS_FROM_GGSN; } return VOS_OK; }