X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=pppd%2Flcp.c;h=2d90432f337ab68fa1c473f90ef35eb645f92126;hb=b77aeba0a75c2a79b01e2b231d0df5ef88c93125;hp=73389bd7a9075afcf84c85c5fac1e44b8f127163;hpb=24af3d4d6dbf452f8acaa1a15a9e08f96a0e6eb2;p=ppp.git diff --git a/pppd/lcp.c b/pppd/lcp.c index 73389bd..2d90432 100644 --- a/pppd/lcp.c +++ b/pppd/lcp.c @@ -17,9 +17,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#ifndef lint -static char rcsid[] = "$Id: lcp.c,v 1.34 1999/02/26 10:34:47 paulus Exp $"; -#endif +#define RCSID "$Id: lcp.c,v 1.47 1999/12/23 01:27:28 paulus Exp $"; /* * TODO: @@ -28,13 +26,6 @@ static char rcsid[] = "$Id: lcp.c,v 1.34 1999/02/26 10:34:47 paulus Exp $"; #include #include #include -#include -#include -#include -#include -#include -#include -#include #include "pppd.h" #include "fsm.h" @@ -42,11 +33,14 @@ static char rcsid[] = "$Id: lcp.c,v 1.34 1999/02/26 10:34:47 paulus Exp $"; #include "chap.h" #include "magic.h" +static const char rcsid[] = RCSID; + /* * LCP-related command-line options. */ int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ +bool lax_recv = 0; /* accept control chars in asyncmap */ static int setescape __P((char **)); @@ -70,7 +64,7 @@ static option_t lcp_option_list[] = { { "-as", o_uint32, &lcp_wantoptions[0].asyncmap, "Set asyncmap (for received packets)", OPT_OR, &lcp_wantoptions[0].neg_asyncmap }, - { "nomagicnumber", o_bool, &lcp_wantoptions[0].neg_magicnumber, + { "nomagic", o_bool, &lcp_wantoptions[0].neg_magicnumber, "Disable magic number negotiation (looped-back line detection)", OPT_A2COPY, &lcp_allowoptions[0].neg_magicnumber }, { "-mn", o_bool, &lcp_wantoptions[0].neg_magicnumber, @@ -111,6 +105,8 @@ static option_t lcp_option_list[] = { "Set maximum number of LCP configure-request transmissions" }, { "lcp-max-failure", o_int, &lcp_fsm[0].maxnakloops, "Set limit on number of LCP configure-naks" }, + { "receive-all", o_bool, &lax_recv, + "Accept all received control characters", 1 }, {NULL} }; @@ -122,9 +118,9 @@ lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ lcp_options lcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ u_int32_t xmit_accm[NUM_PPP][8]; /* extended transmit ACCM */ -static u_int32_t lcp_echos_pending = 0; /* Number of outstanding echo msgs */ -static u_int32_t lcp_echo_number = 0; /* ID number of next echo frame */ -static u_int32_t lcp_echo_timer_running = 0; /* TRUE if a timer is running */ +static int lcp_echos_pending = 0; /* Number of outstanding echo msgs */ +static int lcp_echo_number = 0; /* ID number of next echo frame */ +static int lcp_echo_timer_running = 0; /* set if a timer is running */ static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */ @@ -199,6 +195,7 @@ struct protent lcp_protent = { NULL, 1, "LCP", + NULL, lcp_option_list, NULL, NULL, @@ -212,10 +209,10 @@ int lcp_loopbackfail = DEFLOOPBACKFAIL; */ #define CILEN_VOID 2 #define CILEN_CHAR 3 -#define CILEN_SHORT 4 /* CILEN_VOID + sizeof(short) */ -#define CILEN_CHAP 5 /* CILEN_VOID + sizeof(short) + 1 */ -#define CILEN_LONG 6 /* CILEN_VOID + sizeof(long) */ -#define CILEN_LQR 8 /* CILEN_VOID + sizeof(short) + sizeof(long) */ +#define CILEN_SHORT 4 /* CILEN_VOID + 2 */ +#define CILEN_CHAP 5 /* CILEN_VOID + 2 + 1 */ +#define CILEN_LONG 6 /* CILEN_VOID + 4 */ +#define CILEN_LQR 8 /* CILEN_VOID + 2 + 4 */ #define CILEN_CBCP 3 #define CODENAME(x) ((x) == CONFACK ? "ACK" : \ @@ -276,7 +273,7 @@ lcp_init(unit) implementations */ wo->neg_mru = 1; wo->mru = DEFMRU; - wo->neg_asyncmap = 0; + wo->neg_asyncmap = 1; wo->asyncmap = 0; wo->neg_chap = 0; /* Set to 1 on server */ wo->neg_upap = 0; /* Set to 1 on server */ @@ -339,7 +336,7 @@ lcp_close(unit, reason) fsm *f = &lcp_fsm[unit]; if (phase != PHASE_DEAD) - phase = PHASE_TERMINATE; + new_phase(PHASE_TERMINATE); if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) { /* * This action is not strictly according to the FSM in RFC1548, @@ -371,7 +368,7 @@ lcp_lowerup(unit) */ ppp_set_xaccm(unit, xmit_accm[unit]); ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0); - ppp_recv_config(unit, PPP_MRU, 0xffffffff, + ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff), wo->neg_pcompression, wo->neg_accompression); peer_mru[unit] = PPP_MRU; lcp_allowoptions[unit].asyncmap = xmit_accm[unit][0]; @@ -426,7 +423,6 @@ lcp_extcode(f, code, id, inp, len) case ECHOREQ: if (f->state != OPENED) break; - LCPDEBUG((LOG_INFO, "lcp: Echo-Request, Rcvd id %d", id)); magp = inp; PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp); fsm_sdata(f, ECHOREP, id, inp, len); @@ -461,27 +457,19 @@ lcp_rprotrej(f, inp, len) struct protent *protp; u_short prot; - LCPDEBUG((LOG_INFO, "lcp_rprotrej.")); - - if (len < sizeof (u_short)) { - LCPDEBUG((LOG_INFO, - "lcp_rprotrej: Rcvd short Protocol-Reject packet!")); + if (len < 2) { + LCPDEBUG(("lcp_rprotrej: Rcvd short Protocol-Reject packet!")); return; } GETSHORT(prot, inp); - LCPDEBUG((LOG_INFO, - "lcp_rprotrej: Rcvd Protocol-Reject packet for %x!", - prot)); - /* * Protocol-Reject packets received in any state other than the LCP * OPENED state SHOULD be silently discarded. */ if( f->state != OPENED ){ - LCPDEBUG((LOG_INFO, "Protocol-Reject discarded: LCP in state %d", - f->state)); + LCPDEBUG(("Protocol-Reject discarded: LCP in state %d", f->state)); return; } @@ -494,8 +482,7 @@ lcp_rprotrej(f, inp, len) return; } - syslog(LOG_WARNING, "Protocol-Reject for unsupported protocol 0x%x", - prot); + warn("Protocol-Reject for unsupported protocol 0x%x", prot); } @@ -510,8 +497,7 @@ lcp_protrej(unit) /* * Can't reject LCP! */ - LCPDEBUG((LOG_WARNING, - "lcp_protrej: Received Protocol-Reject for LCP!")); + error("Received Protocol-Reject for LCP!"); fsm_protreject(&lcp_fsm[unit]); } @@ -646,7 +632,7 @@ lcp_addci(f, ucp, lenp) if (ucp - start_ucp != *lenp) { /* this should never happen, because peer_mtu should be 1500 */ - syslog(LOG_ERR, "Bug in lcp_addci: wrong length"); + error("Bug in lcp_addci: wrong length"); } } @@ -775,7 +761,7 @@ lcp_ackci(f, p, len) goto bad; return (1); bad: - LCPDEBUG((LOG_WARNING, "lcp_acki: received bad Ack!")); + LCPDEBUG(("lcp_acki: received bad Ack!")); return (0); } @@ -933,11 +919,18 @@ lcp_nakci(f, p, len) if (go->neg_chap) { /* * We were asking for CHAP/MD5; they must want a different - * algorithm. If they can't do MD5, we'll have to stop + * algorithm. If they can't do MD5, we can ask for M$-CHAP + * if we support it, otherwise we'll have to stop * asking for CHAP. */ - if (cichar != go->chap_mdtype) - try.neg_chap = 0; + if (cichar != go->chap_mdtype) { +#ifdef CHAPMS + if (cichar == CHAP_MICROSOFT) + go->chap_mdtype = CHAP_MICROSOFT; + else +#endif /* CHAPMS */ + try.neg_chap = 0; + } } else { /* * Stop asking for PAP if we were asking for it. @@ -1061,18 +1054,16 @@ lcp_nakci(f, p, len) p = next; } - /* If there is still anything left, this packet is bad. */ - if (len != 0) - goto bad; - /* * OK, the Nak is good. Now we can update state. + * If there are any options left we ignore them. */ if (f->state != OPENED) { if (looped_back) { if (++try.numloops >= lcp_loopbackfail) { - syslog(LOG_NOTICE, "Serial line is looped back."); + notice("Serial line is looped back."); lcp_close(f->unit, "Loopback detected"); + status = EXIT_LOOPBACK; } } else try.numloops = 0; @@ -1082,7 +1073,7 @@ lcp_nakci(f, p, len) return 1; bad: - LCPDEBUG((LOG_WARNING, "lcp_nakci: received bad Nak!")); + LCPDEBUG(("lcp_nakci: received bad Nak!")); return 0; } @@ -1123,7 +1114,6 @@ lcp_rejci(f, p, len) len -= CILEN_VOID; \ INCPTR(CILEN_VOID, p); \ try.neg = 0; \ - LCPDEBUG((LOG_INFO, "lcp_rejci rejected void opt %d", opt)); \ } #define REJCISHORT(opt, neg, val) \ if (go->neg && \ @@ -1137,7 +1127,6 @@ lcp_rejci(f, p, len) if (cishort != val) \ goto bad; \ try.neg = 0; \ - LCPDEBUG((LOG_INFO,"lcp_rejci rejected short opt %d", opt)); \ } #define REJCICHAP(opt, neg, val, digest) \ if (go->neg && \ @@ -1153,7 +1142,6 @@ lcp_rejci(f, p, len) goto bad; \ try.neg = 0; \ try.neg_upap = 0; \ - LCPDEBUG((LOG_INFO,"lcp_rejci rejected chap opt %d", opt)); \ } #define REJCILONG(opt, neg, val) \ if (go->neg && \ @@ -1167,7 +1155,6 @@ lcp_rejci(f, p, len) if (cilong != val) \ goto bad; \ try.neg = 0; \ - LCPDEBUG((LOG_INFO,"lcp_rejci rejected long opt %d", opt)); \ } #define REJCILQR(opt, neg, val) \ if (go->neg && \ @@ -1182,7 +1169,6 @@ lcp_rejci(f, p, len) if (cishort != PPP_LQR || cilong != val) \ goto bad; \ try.neg = 0; \ - LCPDEBUG((LOG_INFO,"lcp_rejci rejected LQR opt %d", opt)); \ } #define REJCICBCP(opt, neg, val) \ if (go->neg && \ @@ -1196,7 +1182,6 @@ lcp_rejci(f, p, len) if (cichar != val) \ goto bad; \ try.neg = 0; \ - LCPDEBUG((LOG_INFO,"lcp_rejci rejected Callback opt %d", opt)); \ } REJCISHORT(CI_MRU, neg_mru, go->mru); @@ -1224,7 +1209,7 @@ lcp_rejci(f, p, len) return 1; bad: - LCPDEBUG((LOG_WARNING, "lcp_rejci: received bad Reject!")); + LCPDEBUG(("lcp_rejci: received bad Reject!")); return 0; } @@ -1274,7 +1259,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) if (l < 2 || /* Not enough data for CI header or */ p[1] < 2 || /* CI length too small or */ p[1] > l) { /* CI length too big? */ - LCPDEBUG((LOG_WARNING, "lcp_reqci: bad CI length!")); + LCPDEBUG(("lcp_reqci: bad CI length!")); orc = CONFREJ; /* Reject bad CI */ cilen = l; /* Reject till end of packet */ l = 0; /* Don't loop again */ @@ -1288,14 +1273,12 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) switch (citype) { /* Check CI type */ case CI_MRU: - LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd MRU")); if (!ao->neg_mru || /* Allow option? */ cilen != CILEN_SHORT) { /* Check CI length */ orc = CONFREJ; /* Reject CI */ break; } GETSHORT(cishort, p); /* Parse MRU */ - LCPDEBUG((LOG_INFO, "(%d)", cishort)); /* * He must be able to receive at least our minimum. @@ -1314,14 +1297,12 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) break; case CI_ASYNCMAP: - LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd ASYNCMAP")); if (!ao->neg_asyncmap || cilen != CILEN_LONG) { orc = CONFREJ; break; } GETLONG(cilong, p); - LCPDEBUG((LOG_INFO, "(%x)", (unsigned int) cilong)); /* * Asyncmap must have set at least the bits @@ -1339,7 +1320,6 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) break; case CI_AUTHTYPE: - LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd AUTHTYPE")); if (cilen < CILEN_SHORT || !(ao->neg_upap || ao->neg_chap)) { /* @@ -1349,10 +1329,9 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) break; } GETSHORT(cishort, p); - LCPDEBUG((LOG_INFO, "(%x)", cishort)); /* - * Authtype must be UPAP or CHAP. + * Authtype must be PAP or CHAP. * * Note: if both ao->neg_upap and ao->neg_chap are set, * and the peer sends a Configure-Request with two @@ -1365,8 +1344,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) if (cishort == PPP_PAP) { if (ho->neg_chap || /* we've already accepted CHAP */ cilen != CILEN_SHORT) { - LCPDEBUG((LOG_WARNING, - "lcp_reqci: rcvd AUTHTYPE PAP, rejecting...")); + LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE PAP, rejecting...")); orc = CONFREJ; break; } @@ -1376,6 +1354,8 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) PUTCHAR(CILEN_CHAP, nakp); PUTSHORT(PPP_CHAP, nakp); PUTCHAR(ao->chap_mdtype, nakp); + /* XXX if we can do CHAP_MICROSOFT as well, we should + probably put in another option saying so */ break; } ho->neg_upap = 1; @@ -1384,8 +1364,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) if (cishort == PPP_CHAP) { if (ho->neg_upap || /* we've already accepted PAP */ cilen != CILEN_CHAP) { - LCPDEBUG((LOG_INFO, - "lcp_reqci: rcvd AUTHTYPE CHAP, rejecting...")); + LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE CHAP, rejecting...")); orc = CONFREJ; break; } @@ -1432,7 +1411,6 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) break; case CI_QUALITY: - LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd QUALITY")); if (!ao->neg_lqr || cilen != CILEN_LQR) { orc = CONFREJ; @@ -1441,7 +1419,6 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) GETSHORT(cishort, p); GETLONG(cilong, p); - LCPDEBUG((LOG_INFO, "(%x %x)", cishort, (unsigned int) cilong)); /* * Check the protocol and the reporting period. @@ -1458,14 +1435,12 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) break; case CI_MAGICNUMBER: - LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd MAGICNUMBER")); if (!(ao->neg_magicnumber || go->neg_magicnumber) || cilen != CILEN_LONG) { orc = CONFREJ; break; } GETLONG(cilong, p); - LCPDEBUG((LOG_INFO, "(%x)", (unsigned int) cilong)); /* * He must have a different magic number. @@ -1485,7 +1460,6 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) case CI_PCOMPRESSION: - LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd PCOMPRESSION")); if (!ao->neg_pcompression || cilen != CILEN_VOID) { orc = CONFREJ; @@ -1495,7 +1469,6 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) break; case CI_ACCOMPRESSION: - LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd ACCOMPRESSION")); if (!ao->neg_accompression || cilen != CILEN_VOID) { orc = CONFREJ; @@ -1505,14 +1478,12 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) break; default: - LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd unknown option %d", - citype)); + LCPDEBUG(("lcp_reqci: rcvd unknown option %d", citype)); orc = CONFREJ; break; } endswitch: - LCPDEBUG((LOG_INFO, " (%s)", CODENAME(orc))); if (orc == CONFACK && /* Good CI */ rc != CONFACK) /* but prior CI wasnt? */ continue; /* Don't send this one */ @@ -1558,7 +1529,7 @@ endswitch: break; } - LCPDEBUG((LOG_INFO, "lcp_reqci: returning CONF%s.", CODENAME(rc))); + LCPDEBUG(("lcp_reqci: returning CONF%s.", CODENAME(rc))); return (rc); /* Return final code */ } @@ -1590,7 +1561,7 @@ lcp_up(f) (ho->neg_asyncmap? ho->asyncmap: 0xffffffff), ho->neg_pcompression, ho->neg_accompression); ppp_recv_config(f->unit, (go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU), - (go->neg_asyncmap? go->asyncmap: 0xffffffff), + (lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff), go->neg_pcompression, go->neg_accompression); if (ho->neg_mru) @@ -1763,7 +1734,7 @@ lcp_printpkt(p, plen, printer, arg) if (olen >= CILEN_CHAR) { p += 2; printer(arg, "callback "); - GETSHORT(cishort, p); + GETCHAR(cishort, p); switch (cishort) { case CBCP_OPT: printer(arg, "CBCP"); @@ -1841,9 +1812,10 @@ void LcpLinkFailure (f) fsm *f; { if (f->state == OPENED) { - syslog(LOG_INFO, "No response to %d echo-requests", lcp_echos_pending); - syslog(LOG_NOTICE, "Serial link appears to be disconnected."); + info("No response to %d echo-requests", lcp_echos_pending); + notice("Serial link appears to be disconnected."); lcp_close(f->unit, "Peer not responding"); + status = EXIT_PEER_DEAD; } } @@ -1856,11 +1828,14 @@ LcpEchoCheck (f) fsm *f; { LcpSendEchoRequest (f); + if (f->state != OPENED) + return; /* * Start the timer for the next interval. */ - assert (lcp_echo_timer_running==0); + if (lcp_echo_timer_running) + warn("assertion lcp_echo_timer_running==0 failed"); TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval); lcp_echo_timer_running = 1; } @@ -1886,19 +1861,21 @@ LcpEchoTimeout (arg) static void lcp_received_echo_reply (f, id, inp, len) fsm *f; - int id; u_char *inp; int len; + int id; + u_char *inp; + int len; { u_int32_t magic; /* Check the magic number - don't count replies from ourselves. */ if (len < 4) { - syslog(LOG_DEBUG, "lcp: received short Echo-Reply, length %d", len); + dbglog("lcp: received short Echo-Reply, length %d", len); return; } GETLONG(magic, inp); if (lcp_gotoptions[f->unit].neg_magicnumber && magic == lcp_gotoptions[f->unit].magicnumber) { - syslog(LOG_WARNING, "appear to have received our own echo-reply!"); + warn("appear to have received our own echo-reply!"); return; }