📄 ppplcp.c
字号:
/*---------------------------------------------------------------*/ /* Check requested option. */ /*---------------------------------------------------------------*/ switch (remote->auth_proto) { case PPP_CHAP_PROTO: /*-----------------------------------------------------------*/ /* Ensure MD5 selected, length correct, and CHAP accepted. */ /*-----------------------------------------------------------*/ --toss; if ((pullchar(pppRcvBuf) != MD5_ALG) || (opt->len != 5) || !(Ppp->public.accept_opts & OPT_CHAP)) { remote->auth_proto = PPP_PAP_PROTO; result = CONFIG_NAK; } break; case PPP_PAP_PROTO: /*-----------------------------------------------------------*/ /* Ensure PAP is accepted and length correct. */ /*-----------------------------------------------------------*/ if (!(Ppp->public.accept_opts & OPT_PAP) || (opt->len != 4)) { remote->auth_proto = PPP_CHAP_PROTO; result = CONFIG_NAK; } break; default: /* unknown */ /*-----------------------------------------------------------*/ /* Suggest accepted protocol, giving preference to CHAP. */ /*-----------------------------------------------------------*/ if (Ppp->public.accept_opts & OPT_CHAP) remote->auth_proto = PPP_CHAP_PROTO; else remote->auth_proto = PPP_PAP_PROTO; result = CONFIG_NAK; break; } break; case LCP_MAGIC: /*---------------------------------------------------------------*/ /* Verify Magic Number option length is correct. */ /*---------------------------------------------------------------*/ if (opt->len != 6) { opt->len = 6; result = CONFIG_NAK; if (toss < 0) toss = 0; break; } /*---------------------------------------------------------------*/ /* Read the peer's requested magic number. */ /*---------------------------------------------------------------*/ remote->magic = pull32(pppRcvBuf); toss -= 4;#if PPP_TRACE pppLog(" checking Magic Number=0x%08X", remote->magic);#endif /*---------------------------------------------------------------*/ /* Ensure the magic numbers are different. */ /*---------------------------------------------------------------*/ if (!remote->magic || (remote->magic == Ppp->lcp.local.magic)) { remote->magic = lcp_rand(); result = CONFIG_NAK; } break; case LCP_PFC: /*---------------------------------------------------------------*/ /* Verify PFC option length is correct. */ /*---------------------------------------------------------------*/ if (opt->len != 2) { opt->len = 2; result = CONFIG_REJ; if (toss < 0) toss = 0; break; }#if PPP_TRACE pppLog(" checking Protocol compression");#endif break; case LCP_ACFC: /*---------------------------------------------------------------*/ /* Verify ACFC option length is correct. */ /*---------------------------------------------------------------*/ if (opt->len != 2) { opt->len = 2; result = CONFIG_REJ; if (toss < 0) toss = 0; break; }#if PPP_TRACE pppLog(" checking Addr/Ctrl compression");#endif break; default: /*---------------------------------------------------------------*/ /* Reject option if we don't recognize it. */ /*---------------------------------------------------------------*/ result = CONFIG_REJ; break; } /*-------------------------------------------------------------------*/ /* Reject option if we are not set to accept it. */ /*-------------------------------------------------------------------*/ if ((Ppp->lcp_accept_opts & (1 << opt->type)) == FALSE) result = CONFIG_REJ; /*-------------------------------------------------------------------*/ /* Return error if buffer ran out of data. */ /*-------------------------------------------------------------------*/ if (toss < 0) return -1; /*-------------------------------------------------------------------*/ /* Toss any remaining bytes in option. */ /*-------------------------------------------------------------------*/ while (toss-- > 0) { if (pullchar(pppRcvBuf) == -1) return -1; } return result;}/***********************************************************************//* check_req: Check peer's configuration request *//* *//* Returns: 0 if able to accept options, else -1 *//* *//***********************************************************************/static int check_req(FSM *fsm, ConfigHdr *config){ int signed_length = config->len; LcpCB *lcp = &Ppp->lcp; NetBuf *rbuf; /* reply packet */ int reply_result = CONFIG_ACK;/* request reply */ int option_result; /* option reply */ uint desired = 0; /* desired to negotiate */ OptHdr option; /* option header storage */ int magic_nak = FALSE; /*-------------------------------------------------------------------*/ /* Attempt to allocate buffer. Return -1 if unable. */ /*-------------------------------------------------------------------*/ rbuf = tcpGetBuf(NIMHLEN + PPP_MTU + CRC16_LEN); if (rbuf == NULL) return -1; /*-------------------------------------------------------------------*/ /* Establish those options that need to reset. */ /*-------------------------------------------------------------------*/ lcp->remote.options = 0; /* all off */ lcp->remote.mru = Ppp->public.mtu; lcp->remote.accm = LCP_ACCM_DEFAULT; lcp->remote.auth_proto = 0; /* no authentication */ /*-------------------------------------------------------------------*/ /* Process each option requested by the peer. */ /*-------------------------------------------------------------------*/ while ((signed_length > 0) && (pppRdOpt(&option) != -1)) { /*-----------------------------------------------------------------*/ /* Verify configuration header length is not too short. */ /*-----------------------------------------------------------------*/ if ((signed_length -= option.len) < 0) {#if PPP_TRACE pppLog("LCP REQ: bad header length");#endif tcpRetBuf(&rbuf); return -1; } /*-----------------------------------------------------------------*/ /* Verify option value is acceptable and packet length is okay. */ /*-----------------------------------------------------------------*/ option_result = check_req_opt(&lcp->remote, &option); if (option_result == -1) {#if PPP_TRACE pppLog("LCP REQ: ran out of data");#endif tcpRetBuf(&rbuf); return -1; }#if PPP_TRACE pppLog("LCP REQ: result=%s, option=%02X, length=%u", fsmCodes[option_result], option.type, option.len);#endif /*-----------------------------------------------------------------*/ /* Record if magic number option was NAKed. */ /*-----------------------------------------------------------------*/ if ((option_result == CONFIG_NAK) && (option.type == LCP_MAGIC)) magic_nak = TRUE; /*-----------------------------------------------------------------*/ /* If NAK reached, ignore ACK options. If REJ reached, ignore ACK */ /* and NAK options. */ /*-----------------------------------------------------------------*/ if (option_result < reply_result) continue; /*-----------------------------------------------------------------*/ /* On transition to NAK or REJ, discard current reply list. */ /*-----------------------------------------------------------------*/ else if (option_result > reply_result) { NetRstBuf(rbuf); reply_result = option_result; } /*-----------------------------------------------------------------*/ /* Remember those option requests we have received. */ /*-----------------------------------------------------------------*/ lcp->remote.options |= (1 << option.type); /*-----------------------------------------------------------------*/ /* Add option response to the return list. */ /*-----------------------------------------------------------------*/ add_option(rbuf, &lcp->remote, option.type); } /*-------------------------------------------------------------------*/ /* If not at NAK limit, append any missing options that are desired. */ /*-------------------------------------------------------------------*/ desired &= ~lcp->remote.options; if ((fsm->rcn_cnt < fsm->pdc->nak_limit) && desired) { switch (reply_result) { case CONFIG_ACK: NetRstBuf(rbuf); reply_result = CONFIG_NAK; /*lint -fallthrough */ case CONFIG_NAK: make_opts(rbuf, &lcp->remote, desired); break; case CONFIG_REJ: /* do nothing */ break; } } /*-------------------------------------------------------------------*/ /* Else check if result is a NAK. */ /*-------------------------------------------------------------------*/ else if (reply_result == CONFIG_NAK) { /*-----------------------------------------------------------------*/ /* If over NAK limit, promote non-magic NAKs to rejects. */ /*-----------------------------------------------------------------*/ if ((fsm->rcn_cnt >= fsm->pdc->nak_limit) && (magic_nak == FALSE)) reply_result = CONFIG_REJ; } /*-------------------------------------------------------------------*/ /* Send ACK, NAK, or REJ to the peer. */ /*-------------------------------------------------------------------*/ pppFsmSend(fsm, reply_result, config->id, rbuf); return reply_result;}/***********************************************************************//* check_ack: Process configuration ACK sent by the peer *//* *//* Returns: 0 if acknowledgment is acceptable, else -1 *//* *//***********************************************************************/static int check_ack(FSM *fsm, ConfigHdr *config){ NetBuf *rbuf; int error = FALSE; /*-------------------------------------------------------------------*/ /* The ID field must match the last request we sent. */ /*-------------------------------------------------------------------*/ if (config->id != fsm->lastid) {#if PPP_TRACE pppLog("LCP ACK: wrong ID");#endif return -1; } /*-------------------------------------------------------------------*/ /* Get a copy of the last request we sent. */ /*-------------------------------------------------------------------*/ rbuf = make_req(fsm);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -