📄 lcp.c
字号:
break; case CI_EPDISC:#if TRACELCP > 0 snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_EPDISC"); traceNdx = strlen(traceBuf);#endif orc = CONFREJ; break; default:#if TRACELCP snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " unknown %d", citype); traceNdx = strlen(traceBuf);#endif orc = CONFREJ; break; } endswitch:#if TRACELCP if (traceNdx >= 80 - 32) { LCPDEBUG(LOG_INFO, ("lcp_reqci: rcvd%s\n", traceBuf)); traceNdx = 0; }#endif if (orc == CONFACK && /* Good CI */ rc != CONFACK) { /* but prior CI wasnt? */ continue; /* Don't send this one */ } if (orc == CONFNAK) { /* Nak this CI? */ if (reject_if_disagree /* Getting fed up with sending NAKs? */ && citype != CI_MAGICNUMBER) { orc = CONFREJ; /* Get tough if so */ } else { if (rc == CONFREJ) { /* Rejecting prior CI? */ continue; /* Don't send this one */ } rc = CONFNAK; } } if (orc == CONFREJ) { /* Reject this CI */ rc = CONFREJ; if (cip != rejp) { /* Need to move rejected CI? */ BCOPY(cip, rejp, cilen); /* Move it */ } INCPTR(cilen, rejp); /* Update output pointer */ } } /* * If we wanted to send additional NAKs (for unsent CIs), the * code would go here. The extra NAKs would go at *nakp. * At present there are no cases where we want to ask the * peer to negotiate an option. */ switch (rc) { case CONFACK: *lenp = (int)(next - inp); break; case CONFNAK: /* * Copy the Nak'd options from the nak_buffer to the caller's buffer. */ *lenp = (int)(nakp - nak_buffer); BCOPY(nak_buffer, inp, *lenp); break; case CONFREJ: *lenp = (int)(rejp - inp); break; }#if TRACELCP > 0 if (traceNdx > 0) { LCPDEBUG(LOG_INFO, ("lcp_reqci: %s\n", traceBuf)); }#endif LCPDEBUG(LOG_INFO, ("lcp_reqci: returning CONF%s.\n", CODENAME(rc))); return (rc); /* Return final code */}/* * lcp_up - LCP has come UP. */static voidlcp_up(fsm *f){ lcp_options *wo = &lcp_wantoptions[f->unit]; lcp_options *ho = &lcp_hisoptions[f->unit]; lcp_options *go = &lcp_gotoptions[f->unit]; lcp_options *ao = &lcp_allowoptions[f->unit]; if (!go->neg_magicnumber) { go->magicnumber = 0; } if (!ho->neg_magicnumber) { ho->magicnumber = 0; } /* * Set our MTU to the smaller of the MTU we wanted and * the MRU our peer wanted. If we negotiated an MRU, * set our MRU to the larger of value we wanted and * the value we got in the negotiation. */ ppp_send_config(f->unit, LWIP_MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)), (ho->neg_asyncmap? ho->asyncmap: 0xffffffffl), ho->neg_pcompression, ho->neg_accompression); /* * If the asyncmap hasn't been negotiated, we really should * set the receive asyncmap to ffffffff, but we set it to 0 * for backwards contemptibility. */ ppp_recv_config(f->unit, (go->neg_mru? LWIP_MAX(wo->mru, go->mru): PPP_MRU), (go->neg_asyncmap? go->asyncmap: 0x00000000), go->neg_pcompression, go->neg_accompression); if (ho->neg_mru) { peer_mru[f->unit] = ho->mru; } lcp_echo_lowerup(f->unit); /* Enable echo messages */ link_established(f->unit); /* The link is up; authenticate now */}/* * lcp_down - LCP has gone DOWN. * * Alert other protocols. */static voidlcp_down(fsm *f){ lcp_options *go = &lcp_gotoptions[f->unit]; lcp_echo_lowerdown(f->unit); link_down(f->unit); ppp_send_config(f->unit, PPP_MRU, 0xffffffffl, 0, 0); ppp_recv_config(f->unit, PPP_MRU, (go->neg_asyncmap? go->asyncmap: 0x00000000), go->neg_pcompression, go->neg_accompression); peer_mru[f->unit] = PPP_MRU;}/* * lcp_starting - LCP needs the lower layer up. */static voidlcp_starting(fsm *f){ link_required(f->unit); /* lwip: currently does nothing */}/* * lcp_finished - LCP has finished with the lower layer. */static voidlcp_finished(fsm *f){ link_terminated(f->unit); /* we are finished with the link */}#if PPP_ADDITIONAL_CALLBACKS/* * print_string - print a readable representation of a string using * printer. */static voidprint_string( char *p, int len, void (*printer) (void *, char *, ...), void *arg){ int c; printer(arg, "\""); for (; len > 0; --len) { c = *p++; if (' ' <= c && c <= '~') { if (c == '\\' || c == '"') { printer(arg, "\\"); } printer(arg, "%c", c); } else { switch (c) { case '\n': printer(arg, "\\n"); break; case '\r': printer(arg, "\\r"); break; case '\t': printer(arg, "\\t"); break; default: printer(arg, "\\%.3o", c); } } } printer(arg, "\"");}/* * lcp_printpkt - print the contents of an LCP packet. */static char *lcp_codenames[] = { "ConfReq", "ConfAck", "ConfNak", "ConfRej", "TermReq", "TermAck", "CodeRej", "ProtRej", "EchoReq", "EchoRep", "DiscReq"};static intlcp_printpkt( u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg){ int code, id, len, olen; u_char *pstart, *optend; u_short cishort; u32_t cilong; if (plen < HEADERLEN) { return 0; } pstart = p; GETCHAR(code, p); GETCHAR(id, p); GETSHORT(len, p); if (len < HEADERLEN || len > plen) { return 0; } if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *)) { printer(arg, " %s", lcp_codenames[code-1]); } else { printer(arg, " code=0x%x", code); } printer(arg, " id=0x%x", id); len -= HEADERLEN; switch (code) { case CONFREQ: case CONFACK: case CONFNAK: case CONFREJ: /* print option list */ while (len >= 2) { GETCHAR(code, p); GETCHAR(olen, p); p -= 2; if (olen < 2 || olen > len) { break; } printer(arg, " <"); len -= olen; optend = p + olen; switch (code) { case CI_MRU: if (olen == CILEN_SHORT) { p += 2; GETSHORT(cishort, p); printer(arg, "mru %d", cishort); } break; case CI_ASYNCMAP: if (olen == CILEN_LONG) { p += 2; GETLONG(cilong, p); printer(arg, "asyncmap 0x%lx", cilong); } break; case CI_AUTHTYPE: if (olen >= CILEN_SHORT) { p += 2; printer(arg, "auth "); GETSHORT(cishort, p); switch (cishort) { case PPP_PAP: printer(arg, "pap"); break; case PPP_CHAP: printer(arg, "chap"); break; default: printer(arg, "0x%x", cishort); } } break; case CI_QUALITY: if (olen >= CILEN_SHORT) { p += 2; printer(arg, "quality "); GETSHORT(cishort, p); switch (cishort) { case PPP_LQR: printer(arg, "lqr"); break; default: printer(arg, "0x%x", cishort); } } break; case CI_CALLBACK: if (olen >= CILEN_CHAR) { p += 2; printer(arg, "callback "); GETSHORT(cishort, p); switch (cishort) { case CBCP_OPT: printer(arg, "CBCP"); break; default: printer(arg, "0x%x", cishort); } } break; case CI_MAGICNUMBER: if (olen == CILEN_LONG) { p += 2; GETLONG(cilong, p); printer(arg, "magic 0x%x", cilong); } break; case CI_PCOMPRESSION: if (olen == CILEN_VOID) { p += 2; printer(arg, "pcomp"); } break; case CI_ACCOMPRESSION: if (olen == CILEN_VOID) { p += 2; printer(arg, "accomp"); } break; } while (p < optend) { GETCHAR(code, p); printer(arg, " %.2x", code); } printer(arg, ">"); } break; case TERMACK: case TERMREQ: if (len > 0 && *p >= ' ' && *p < 0x7f) { printer(arg, " "); print_string((char*)p, len, printer, arg); p += len; len = 0; } break; case ECHOREQ: case ECHOREP: case DISCREQ: if (len >= 4) { GETLONG(cilong, p); printer(arg, " magic=0x%x", cilong); p += 4; len -= 4; } break; } /* print the rest of the bytes in the packet */ for (; len > 0; --len) { GETCHAR(code, p); printer(arg, " %.2x", code); } return (int)(p - pstart);}#endif /* PPP_ADDITIONAL_CALLBACKS *//* * Time to shut down the link because there is nothing out there. */static voidLcpLinkFailure (fsm *f){ if (f->state == LS_OPENED) { LCPDEBUG(LOG_INFO, ("No response to %d echo-requests\n", lcp_echos_pending)); LCPDEBUG(LOG_NOTICE, ("Serial link appears to be disconnected.\n")); lcp_close(f->unit, "Peer not responding"); }}/* * Timer expired for the LCP echo requests from this process. */static voidLcpEchoCheck (fsm *f){ LcpSendEchoRequest (f); /* * Start the timer for the next interval. */ LWIP_ASSERT("lcp_echo_timer_running == 0", lcp_echo_timer_running == 0); TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval); lcp_echo_timer_running = 1;}/* * LcpEchoTimeout - Timer expired on the LCP echo */static voidLcpEchoTimeout (void *arg){ if (lcp_echo_timer_running != 0) { lcp_echo_timer_running = 0; LcpEchoCheck ((fsm *) arg); }}/* * LcpEchoReply - LCP has received a reply to the echo */static voidlcp_received_echo_reply (fsm *f, int id, u_char *inp, int len){ u32_t magic; LWIP_UNUSED_ARG(id); /* Check the magic number - don't count replies from ourselves. */ if (len < 4) { LCPDEBUG(LOG_WARNING, ("lcp: received short Echo-Reply, length %d\n", len)); return; } GETLONG(magic, inp); if (lcp_gotoptions[f->unit].neg_magicnumber && magic == lcp_gotoptions[f->unit].magicnumber) { LCPDEBUG(LOG_WARNING, ("appear to have received our own echo-reply!\n")); return; } /* Reset the number of outstanding echo frames */ lcp_echos_pending = 0;}/* * LcpSendEchoRequest - Send an echo request frame to the peer */static voidLcpSendEchoRequest (fsm *f){ u32_t lcp_magic; u_char pkt[4], *pktp; /* * Detect the failure of the peer at this point. */ if (lcp_echo_fails != 0) { if (lcp_echos_pending >= lcp_echo_fails) { LcpLinkFailure(f); lcp_echos_pending = 0; } } /* * Make and send the echo request frame. */ if (f->state == LS_OPENED) { lcp_magic = lcp_gotoptions[f->unit].magicnumber; pktp = pkt; PUTLONG(lcp_magic, pktp); fsm_sdata(f, ECHOREQ, (u_char)(lcp_echo_number++ & 0xFF), pkt, (int)(pktp - pkt)); ++lcp_echos_pending; }}/* * lcp_echo_lowerup - Start the timer for the LCP frame */static voidlcp_echo_lowerup (int unit){ fsm *f = &lcp_fsm[unit]; /* Clear the parameters for generating echo frames */ lcp_echos_pending = 0; lcp_echo_number = 0; lcp_echo_timer_running = 0; /* If a timeout interval is specified then start the timer */ if (lcp_echo_interval != 0) { LcpEchoCheck (f); }}/* * lcp_echo_lowerdown - Stop the timer for the LCP frame */static voidlcp_echo_lowerdown (int unit){ fsm *f = &lcp_fsm[unit]; if (lcp_echo_timer_running != 0) { UNTIMEOUT (LcpEchoTimeout, f); lcp_echo_timer_running = 0; }}#endif /* PPP_SUPPORT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -