X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=pppd%2Flcp.c;h=cfaef7a0bd4339c8172c5b1a7c717ca85aed69f1;hb=84a45df38be25f0f4859186ee8e69ebe8c109e4c;hp=231b7e4552861ea828cb361e9923bccf83c061d3;hpb=2c872bc67b83b91ba6390f6e5e72be08e09811a1;p=ppp.git diff --git a/pppd/lcp.c b/pppd/lcp.c index 231b7e4..cfaef7a 100644 --- a/pppd/lcp.c +++ b/pppd/lcp.c @@ -17,7 +17,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define RCSID "$Id: lcp.c,v 1.48 2000/03/27 06:02:59 paulus Exp $"; +#define RCSID "$Id: lcp.c,v 1.55 2000/04/29 12:32:09 paulus Exp $" /* * TODO: @@ -41,9 +41,14 @@ static const char rcsid[] = RCSID; 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 */ +bool noendpoint = 0; /* don't send/accept endpoint discriminator */ static int setescape __P((char **)); +#ifdef HAVE_MULTILINK +static int setendpoint __P((char **)); +#endif /* HAVE_MULTILINK */ + static option_t lcp_option_list[] = { /* LCP options */ { "noaccomp", o_bool, &lcp_wantoptions[0].neg_accompression, @@ -91,7 +96,7 @@ static option_t lcp_option_list[] = { "Set passive mode", 1 }, { "silent", o_bool, &lcp_wantoptions[0].silent, "Set silent mode", 1 }, - { "escape", o_special, setescape, + { "escape", o_special, (void *)setescape, "List of character codes to escape on transmission" }, { "lcp-echo-failure", o_int, &lcp_echo_fails, "Set number of consecutive echo failures to indicate link failure" }, @@ -108,13 +113,20 @@ static option_t lcp_option_list[] = { { "receive-all", o_bool, &lax_recv, "Accept all received control characters", 1 }, #ifdef HAVE_MULTILINK + { "mrru", o_int, &lcp_wantoptions[0].mrru, + "Maximum received packet size for multilink bundle", + 0, &lcp_wantoptions[0].neg_mrru }, { "mpshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf, "Use short sequence numbers in multilink headers", - OPT_A2COPY, &lcp_allowoptions[0].neg_ssnhf }, + OPT_A2COPY | 1, &lcp_allowoptions[0].neg_ssnhf }, { "nompshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf, "Don't use short sequence numbers in multilink headers", OPT_A2COPY, &lcp_allowoptions[0].neg_ssnhf }, + { "endpoint", o_special, setendpoint, + "Endpoint discriminator for multilink" }, #endif /* HAVE_MULTILINK */ + { "noendpoint", o_bool, &noendpoint, + "Don't send or accept multilink endpoint discriminator", 1 }, {NULL} }; @@ -124,7 +136,7 @@ lcp_options lcp_wantoptions[NUM_PPP]; /* Options that we want to request */ lcp_options lcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ 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 */ +u_int32_t xmit_accm[NUM_PPP][8]; /* extended transmit ACCM */ static int lcp_echos_pending = 0; /* Number of outstanding echo msgs */ static int lcp_echo_number = 0; /* ID number of next echo frame */ @@ -258,6 +270,20 @@ setescape(argv) return ret; } +#ifdef HAVE_MULTILINK +static int +setendpoint(argv) + char **argv; +{ + if (str_to_epdisc(&lcp_wantoptions[0].endpoint, *argv)) { + lcp_wantoptions[0].neg_endpoint = 1; + return 1; + } + option_error("Can't parse '%s' as an endpoint discriminator", *argv); + return 0; +} +#endif /* HAVE_MULTILINK */ + /* * lcp_init - Initialize LCP. */ @@ -275,41 +301,31 @@ lcp_init(unit) fsm_init(f); - wo->passive = 0; - wo->silent = 0; - wo->restart = 0; /* Set to 1 in kernels or multi-line - implementations */ + BZERO(wo, sizeof(*wo)); wo->neg_mru = 1; wo->mru = DEFMRU; 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 */ wo->chap_mdtype = CHAP_DIGEST_MD5; wo->neg_magicnumber = 1; wo->neg_pcompression = 1; wo->neg_accompression = 1; - wo->neg_lqr = 0; /* no LQR implementation yet */ - wo->neg_cbcp = 0; + BZERO(ao, sizeof(*ao)); ao->neg_mru = 1; ao->mru = MAXMRU; ao->neg_asyncmap = 1; - ao->asyncmap = 0; ao->neg_chap = 1; ao->chap_mdtype = CHAP_DIGEST_MD5; ao->neg_upap = 1; ao->neg_magicnumber = 1; ao->neg_pcompression = 1; ao->neg_accompression = 1; - ao->neg_lqr = 0; /* no LQR implementation yet */ #ifdef CBCP_SUPPORT ao->neg_cbcp = 1; -#else - ao->neg_cbcp = 0; #endif + ao->neg_endpoint = 1; - memset(xmit_accm[unit], 0, sizeof(xmit_accm[0])); + BZERO(xmit_accm[unit], sizeof(xmit_accm[0])); xmit_accm[unit][3] = 0x60000000; } @@ -539,12 +555,19 @@ lcp_resetci(f) fsm *f; { lcp_options *wo = &lcp_wantoptions[f->unit]; + lcp_options *go = &lcp_gotoptions[f->unit]; + lcp_options *ao = &lcp_allowoptions[f->unit]; wo->magicnumber = magic(); wo->numloops = 0; - if (!wo->neg_multilink) - wo->neg_ssnhf = 0; - lcp_gotoptions[f->unit] = *wo; + *go = *wo; + if (!multilink) { + go->neg_mrru = 0; + go->neg_ssnhf = 0; + go->neg_endpoint = 0; + } + if (noendpoint) + ao->neg_endpoint = 0; peer_mru[f->unit] = PPP_MRU; auth_reset(f->unit); } @@ -578,9 +601,9 @@ lcp_cilen(f) LENCILONG(go->neg_magicnumber) + LENCIVOID(go->neg_pcompression) + LENCIVOID(go->neg_accompression) + - LENCISHORT(go->neg_multilink) + + LENCISHORT(go->neg_mrru) + LENCIVOID(go->neg_ssnhf) + - (go->neg_endpoint? CILEN_CHAR + go->endp_len: 0)); + (go->neg_endpoint? CILEN_CHAR + go->endpoint.length: 0)); } @@ -653,10 +676,10 @@ lcp_addci(f, ucp, lenp) ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression); ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression); - ADDCISHORT(CI_MRRU, go->neg_multilink, go->mrru); + ADDCISHORT(CI_MRRU, go->neg_mrru, go->mrru); ADDCIVOID(CI_SSNHF, go->neg_ssnhf); - ADDCIENDP(CI_EPDISC, go->neg_endpoint, go->endp_class, go->endpoint, - go->endp_len); + ADDCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class, + go->endpoint.value, go->endpoint.length); if (ucp - start_ucp != *lenp) { /* this should never happen, because peer_mtu should be 1500 */ @@ -800,10 +823,10 @@ lcp_ackci(f, p, len) ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression); ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression); - ACKCISHORT(CI_MRRU, go->neg_multilink, go->mrru); + ACKCISHORT(CI_MRRU, go->neg_mrru, go->mrru); ACKCIVOID(CI_SSNHF, go->neg_ssnhf); - ACKCIENDP(CI_EPDISC, go->neg_endpoint, go->endp_class, go->endpoint, - go->endp_len); + ACKCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class, + go->endpoint.value, go->endpoint.length); /* * If there are any remaining CIs, then this packet is bad. @@ -1052,8 +1075,8 @@ lcp_nakci(f, p, len) * Nak for MRRU option - accept their value if it is smaller * than the one we want. */ - if (go->neg_multilink) { - NAKCISHORT(CI_MRRU, neg_multilink, + if (go->neg_mrru) { + NAKCISHORT(CI_MRRU, neg_mrru, if (cishort <= wo->mrru) try.mrru = cishort; ); @@ -1134,7 +1157,7 @@ lcp_nakci(f, p, len) goto bad; break; case CI_MRRU: - if (go->neg_multilink || no.neg_multilink || cilen != CILEN_SHORT) + if (go->neg_mrru || no.neg_mrru || cilen != CILEN_SHORT) goto bad; break; case CI_SSNHF: @@ -1286,7 +1309,7 @@ lcp_rejci(f, p, len) p[1] == CILEN_CHAR + vlen) { \ int i; \ len -= CILEN_CHAR + vlen; \ - INCPTR(p[1], p); \ + INCPTR(2, p); \ GETCHAR(cichar, p); \ if (cichar != class) \ goto bad; \ @@ -1309,10 +1332,10 @@ lcp_rejci(f, p, len) REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber); REJCIVOID(CI_PCOMPRESSION, neg_pcompression); REJCIVOID(CI_ACCOMPRESSION, neg_accompression); - REJCISHORT(CI_MRRU, neg_multilink, go->mrru); + REJCISHORT(CI_MRRU, neg_mrru, go->mrru); REJCIVOID(CI_SSNHF, neg_ssnhf); - REJCIENDP(CI_EPDISC, neg_endpoint, go->endp_class, go->endpoint, - go->endp_len); + REJCIENDP(CI_EPDISC, neg_endpoint, go->endpoint.class, + go->endpoint.value, go->endpoint.length); /* * If there are any remaining CIs, then this packet is bad. @@ -1596,7 +1619,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) break; case CI_MRRU: - if (!ao->neg_multilink || + if (!ao->neg_mrru || !multilink || cilen != CILEN_SHORT) { orc = CONFREJ; break; @@ -1604,12 +1627,12 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) GETSHORT(cishort, p); /* possibly should insist on a minimum/maximum MRRU here */ - ho->neg_multilink = 1; + ho->neg_mrru = 1; ho->mrru = cishort; break; case CI_SSNHF: - if (!ao->neg_ssnhf || + if (!ao->neg_ssnhf || !multilink || cilen != CILEN_VOID) { orc = CONFREJ; break; @@ -1627,9 +1650,9 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) GETCHAR(cichar, p); cilen -= CILEN_CHAR; ho->neg_endpoint = 1; - ho->endp_class = cichar; - ho->endp_len = cilen; - BCOPY(p, ho->endpoint, cilen); + ho->endpoint.class = cichar; + ho->endpoint.length = cilen; + BCOPY(p, ho->endpoint.value, cilen); INCPTR(cilen, p); break; @@ -1783,10 +1806,6 @@ static char *lcp_codenames[] = { "EchoReq", "EchoRep", "DiscReq" }; -static char *endp_class_names[] = { - "null", "local", "IP", "MAC", "magic", "phone" -}; - static int lcp_printpkt(p, plen, printer, arg) u_char *p; @@ -1796,7 +1815,6 @@ lcp_printpkt(p, plen, printer, arg) { int code, id, len, olen, i; u_char *pstart, *optend; - u_char cichar; u_short cishort; u_int32_t cilong; @@ -1938,15 +1956,23 @@ lcp_printpkt(p, plen, printer, arg) } break; case CI_EPDISC: +#ifdef HAVE_MULTILINK if (olen >= CILEN_CHAR) { + struct epdisc epd; p += 2; - GETCHAR(cichar, p); - if (cichar <= 5) - printer(arg, "endpoint [%s]:", - endp_class_names[cichar]); - else - printer(arg, "endpoint [%d]:"); + GETCHAR(epd.class, p); + epd.length = olen - CILEN_CHAR; + if (epd.length > MAX_ENDP_LEN) + epd.length = MAX_ENDP_LEN; + if (epd.length > 0) { + BCOPY(p, epd.value, epd.length); + p += epd.length; + } + printer(arg, "endpoint [%s]", epdisc_to_str(&epd)); } +#else + printer(arg, "endpoint"); +#endif break; } while (p < optend) { @@ -1961,7 +1987,7 @@ lcp_printpkt(p, plen, printer, arg) case TERMREQ: if (len > 0 && *p >= ' ' && *p < 0x7f) { printer(arg, " "); - print_string(p, len, printer, arg); + print_string((char *)p, len, printer, arg); p += len; len = 0; }