📄 pppfsm.c
字号:
/*-------------------------------------------------------------------*/ /* Determine packet ID based on code type. */ /*-------------------------------------------------------------------*/ switch (code) { case CONFIG_REQ: case TERM_REQ: case ECHO_REQ: /*---------------------------------------------------------------*/ /* Save ID field for match against replies from remote host. */ /*---------------------------------------------------------------*/ fsm->lastid = Ppp->id; /*lint -fallthrough */ case CODE_REJ: case PROT_REJ: case DISCARD_REQ: /*---------------------------------------------------------------*/ /* Use a unique ID field value. */ /*---------------------------------------------------------------*/ hdr.id = Ppp->id++; break; case CONFIG_ACK: case CONFIG_NAK: case CONFIG_REJ: case TERM_ACK: case ECHO_REPLY: /*---------------------------------------------------------------*/ /* Use ID sent by remote host. */ /*---------------------------------------------------------------*/ hdr.id = id; break; default: /*---------------------------------------------------------------*/ /* We're in trouble. */ /*---------------------------------------------------------------*/#if PPP_TRACE pppLogn("PPP/%s %s; Send with bogus code: %d", fsm->pdc->name, fsmStates[fsm->state], code);#endif tcpRetBuf(&buf); return; } /*-------------------------------------------------------------------*/ /* Prepend our magic number for these packet types. */ /*-------------------------------------------------------------------*/ switch (code) { case ECHO_REQ: case ECHO_REPLY: case DISCARD_REQ: { buf->length += 4; buf->ip_pkt -= 4; put32(buf->ip_pkt, Ppp->lcp.local.magic); } } /*-------------------------------------------------------------------*/ /* Clip packet length to peer's working MRU (adjusted for write). */ /*-------------------------------------------------------------------*/ buf->length = min(buf->length, Ppp->lcp.remote.mru - CONFIG_HDR_LEN); /*-------------------------------------------------------------------*/ /* Assign header code and length, and prepend to packet data. */ /*-------------------------------------------------------------------*/ hdr.code = code; hdr.len = buf->length + CONFIG_HDR_LEN; wr_conf(&hdr, buf); /*-------------------------------------------------------------------*/ /* Optionally record event. */ /*-------------------------------------------------------------------*/#if PPP_TRACE pppLogn("PPP/%s %s: sent %s, id=%u, len=%u", fsm->pdc->name, fsmStates[fsm->state], fsmCodes[code], hdr.id, hdr.len);#endif /*-------------------------------------------------------------------*/ /* Prepend PPP header and queue for serial output. */ /*-------------------------------------------------------------------*/ ++Ppp->txOctet[fsm->pdc->fsmi]; PppOutput(fsm->pdc->protocol, buf);}/***********************************************************************//* fsmSendReq: Send a configuration request *//* *//***********************************************************************/void fsmSendReq(FSM *fsm){ NetBuf *buf; /*-------------------------------------------------------------------*/ /* Error return if retry limit exceeded. */ /*-------------------------------------------------------------------*/ if ((fsm->retry == 0) || (fsm->rcn_cnt >= RCN_LIMIT)) return; /*-------------------------------------------------------------------*/ /* Count this try and start timeout timer. */ /*-------------------------------------------------------------------*/ --fsm->retry; fsm_timer(fsm); /*-------------------------------------------------------------------*/ /* If able to build the request, send it. */ /*-------------------------------------------------------------------*/ buf = fsm->pdc->makereq(fsm); if (buf) pppFsmSend(fsm, CONFIG_REQ, 0, buf);}/***********************************************************************//* PppFsmProc: Process incoming packet *//* *//***********************************************************************/void PppFsmProc(FSM *fsm){ int code; ConfigHdr hdr; /*-------------------------------------------------------------------*/ /* Extract configuration header from packet. */ /*-------------------------------------------------------------------*/ if (pppRdConf(&hdr, pppRcvBuf) == -1) {#if PPP_TRACE pppFsmLog(fsm, "short configuration packet");#endif return; } /*-------------------------------------------------------------------*/ /* Optionally record event. */ /*-------------------------------------------------------------------*/#if PPP_TRACE pppLogn("PPP/%s %s: rcvd %s, id=%u, len=%u", fsm->pdc->name, fsmStates[fsm->state], fsmCodes[hdr.code], hdr.id, hdr.len + CONFIG_HDR_LEN);#endif /*-------------------------------------------------------------------*/ /* Check for packets received in Initial or Starting states. */ /*-------------------------------------------------------------------*/ if (fsm->state < fsmCLOSED) {#if PPP_TRACE pppFsmLog(fsm, "Illegal transition");#endif return; } /*-------------------------------------------------------------------*/ /* Treat unused codes as unrecognized codes. */ /*-------------------------------------------------------------------*/ code = hdr.code; if (((1 << code) & fsm->pdc->recognize) == 0) code = UNRECOGNIZED; /*-------------------------------------------------------------------*/ /* Process the header code according to the current state. */ /*-------------------------------------------------------------------*/ switch (code) { case CONFIG_REQ: switch (fsm->state) { case fsmCLOSED: send_term_ack(fsm, hdr.id); break; case fsmOPENED: /* Unexpected event? */ fsm->pdc->down(fsm); /*lint -fallthrough */ case fsmSTOPPED: set_retry_count(fsm, fsm->pdc->req_limit); fsmSendReq(fsm); /*lint -fallthrough */ case fsmReqSent: case fsmAckSent: /*-----------------------------------------------------------*/ /* Check option requests and send ACK/NAK/REJ reply to peer. */ /*-----------------------------------------------------------*/ if (fsm->pdc->request(fsm, &hdr) == CONFIG_ACK) fsm->state = fsmAckSent; else { ++fsm->rcn_cnt; fsm->state = fsmReqSent; } break; case fsmAckRcvd: /*-----------------------------------------------------------*/ /* Check option requests and send ACK/NAK/REJ reply to peer. */ /*-----------------------------------------------------------*/ if (fsm->pdc->request(fsm, &hdr) == CONFIG_ACK) this_layer_up(fsm); else { ++fsm->rcn_cnt; fsm_timer(fsm); /* give peer time to respond */ } break; case fsmCLOSING: case fsmSTOPPING: /*-----------------------------------------------------------*/ /* Waiting for timeout. The connection is being closed. */ /*-----------------------------------------------------------*/ break; } break; case CONFIG_ACK: switch (fsm->state) { case fsmCLOSED: case fsmSTOPPED: send_term_ack(fsm, hdr.id); break; case fsmCLOSING: case fsmSTOPPING: /*-----------------------------------------------------------*/ /* Waiting for timeout. The connection is being closed. */ /*-----------------------------------------------------------*/ break; case fsmReqSent: if (fsm->pdc->ack(fsm, &hdr) == 0) { set_retry_count(fsm, fsm->pdc->req_limit); fsm->state = fsmAckRcvd; } break; case fsmOPENED: /* Unexpected event */ fsm->pdc->down(fsm); /*lint -fallthrough */ case fsmAckRcvd: /* Unexpected event */#if PPP_TRACE pppFsmLog(fsm, "peer error likely");#endif fsm->state = fsmReqSent; fsmSendReq(fsm); break; case fsmAckSent: if (fsm->pdc->ack(fsm, &hdr) == 0) { set_retry_count(fsm, fsm->pdc->req_limit); this_layer_up(fsm); } break; } break; case CONFIG_NAK: switch (fsm->state) { case fsmCLOSED: case fsmSTOPPED: send_term_ack(fsm, hdr.id); break; case fsmCLOSING: case fsmSTOPPING: /*-----------------------------------------------------------*/ /* Waiting for timeout. The connection is being closed. */ /*-----------------------------------------------------------*/ break; case fsmReqSent: case fsmAckSent: /*-----------------------------------------------------------*/ /* Update our config request to reflect NAKed options. */ /*-----------------------------------------------------------*/ if (fsm->pdc->nak(fsm, &hdr) == 0) { set_retry_count(fsm, fsm->pdc->req_limit); fsmSendReq(fsm); } break; case fsmOPENED: /* Unexpected event */ fsm->pdc->down(fsm); /*lint -fallthrough */ case fsmAckRcvd: /* Unexpected event */#if PPP_TRACE pppFsmLog(fsm, "peer error likely");#endif fsm->state = fsmReqSent; fsmSendReq(fsm); break; } break; case CONFIG_REJ: switch (fsm->state) { case fsmCLOSED: case fsmSTOPPED: send_term_ack(fsm, hdr.id); break; case fsmCLOSING: case fsmSTOPPING: /*-----------------------------------------------------------*/ /* Waiting for timeout. The connection is being closed. */ /*-----------------------------------------------------------*/ break; case fsmReqSent: case fsmAckSent: /*-----------------------------------------------------------*/ /* Update our config request to reflect rejected options. */ /*-----------------------------------------------------------*/ if (fsm->pdc->reject(fsm, &hdr) == 0) { set_retry_count(fsm, fsm->pdc->req_limit); fsmSendReq(fsm); } break; case fsmOPENED: /* Unexpected event */ fsm->pdc->down(fsm); /*lint -fallthrough */ case fsmAckRcvd: /* Unexpected event */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -