X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Flcp.c;h=48c1b5168b64f687d5e06cc5315b47485b4147ad;hp=d3c16b804bd64ef21a0dc6ac8ad38fb57ec9d04c;hb=54a510907ca30d8a1651fdb5f7c2c360f4ef7e27;hpb=b23c0e45fbda6d56462c431b2df4f86f38a6cfdd diff --git a/pppd/lcp.c b/pppd/lcp.c index d3c16b8..48c1b51 100644 --- a/pppd/lcp.c +++ b/pppd/lcp.c @@ -18,7 +18,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: lcp.c,v 1.27 1996/07/01 01:15:19 paulus Exp $"; +static char rcsid[] = "$Id: lcp.c,v 1.30 1997/04/30 05:52:59 paulus Exp $"; #endif /* @@ -78,10 +78,11 @@ static void lcp_rprotrej __P((fsm *, u_char *, int)); static void lcp_echo_lowerup __P((int)); static void lcp_echo_lowerdown __P((int)); -static void LcpEchoTimeout __P((caddr_t)); +static void LcpEchoTimeout __P((void *)); static void lcp_received_echo_reply __P((fsm *, int, u_char *, int)); static void LcpSendEchoRequest __P((fsm *)); static void LcpLinkFailure __P((fsm *)); +static void LcpEchoCheck __P((fsm *)); static fsm_callbacks lcp_callbacks = { /* LCP callback routines */ lcp_resetci, /* Reset our Configuration Information */ @@ -136,10 +137,12 @@ int lcp_loopbackfail = DEFLOOPBACKFAIL; * Length of each type of configuration option (in octets) */ #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_CBCP 3 #define CODENAME(x) ((x) == CONFACK ? "ACK" : \ (x) == CONFNAK ? "NAK" : "REJ") @@ -177,6 +180,7 @@ lcp_init(unit) wo->neg_pcompression = 1; wo->neg_accompression = 1; wo->neg_lqr = 0; /* no LQR implementation yet */ + wo->neg_cbcp = 0; ao->neg_mru = 1; ao->mru = MAXMRU; @@ -189,6 +193,11 @@ lcp_init(unit) 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 memset(xmit_accm[unit], 0, sizeof(xmit_accm[0])); xmit_accm[unit][3] = 0x60000000; @@ -224,7 +233,8 @@ lcp_close(unit, reason) { fsm *f = &lcp_fsm[unit]; - phase = PHASE_TERMINATE; + if (phase != PHASE_DEAD) + phase = PHASE_TERMINATE; if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) { /* * This action is not strictly according to the FSM in RFC1548, @@ -451,6 +461,7 @@ lcp_cilen(f) #define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0) #define LENCILONG(neg) ((neg) ? CILEN_LONG : 0) #define LENCILQR(neg) ((neg) ? CILEN_LQR: 0) +#define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0) /* * NB: we only ask for one of CHAP and UPAP, even if we will * accept either. @@ -460,6 +471,7 @@ lcp_cilen(f) LENCICHAP(go->neg_chap) + LENCISHORT(!go->neg_chap && go->neg_upap) + LENCILQR(go->neg_lqr) + + LENCICBCP(go->neg_cbcp) + LENCILONG(go->neg_magicnumber) + LENCIVOID(go->neg_pcompression) + LENCIVOID(go->neg_accompression)); @@ -509,6 +521,12 @@ lcp_addci(f, ucp, lenp) PUTSHORT(PPP_LQR, ucp); \ PUTLONG(val, ucp); \ } +#define ADDCICHAR(opt, neg, val) \ + if (neg) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_CHAR, ucp); \ + PUTCHAR(val, ucp); \ + } ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru); ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, @@ -516,6 +534,7 @@ lcp_addci(f, ucp, lenp) ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype); ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); + ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression); ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression); @@ -574,6 +593,19 @@ lcp_ackci(f, p, len) if (cishort != val) \ goto bad; \ } +#define ACKCICHAR(opt, neg, val) \ + if (neg) { \ + if ((len -= CILEN_CHAR) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_CHAR || \ + citype != opt) \ + goto bad; \ + GETCHAR(cichar, p); \ + if (cichar != val) \ + goto bad; \ + } #define ACKCICHAP(opt, neg, val, digest) \ if (neg) { \ if ((len -= CILEN_CHAP) < 0) \ @@ -626,6 +658,7 @@ lcp_ackci(f, p, len) ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype); ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); + ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression); ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression); @@ -697,6 +730,17 @@ lcp_nakci(f, p, len) no.neg = 1; \ code \ } +#define NAKCICHAR(opt, neg, code) \ + if (go->neg && \ + len >= CILEN_CHAR && \ + p[1] == CILEN_CHAR && \ + p[0] == opt) { \ + len -= CILEN_CHAR; \ + INCPTR(2, p); \ + GETCHAR(cichar, p); \ + no.neg = 1; \ + code \ + } #define NAKCISHORT(opt, neg, code) \ if (go->neg && \ len >= CILEN_SHORT && \ @@ -821,6 +865,13 @@ lcp_nakci(f, p, len) try.lqr_period = cilong; ); + /* + * Only implementing CBCP...not the rest of the callback options + */ + NAKCICHAR(CI_CALLBACK, neg_cbcp, + try.neg_cbcp = 0; + ); + /* * Check for a looped-back line. */ @@ -866,7 +917,7 @@ lcp_nakci(f, p, len) switch (citype) { case CI_MRU: - if (go->neg_mru && go->mru != DEFMRU + if ((go->neg_mru && go->mru != DEFMRU) || no.neg_mru || cilen != CILEN_SHORT) goto bad; GETSHORT(cishort, p); @@ -874,7 +925,7 @@ lcp_nakci(f, p, len) try.mru = cishort; break; case CI_ASYNCMAP: - if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF + if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) || no.neg_asyncmap || cilen != CILEN_LONG) goto bad; break; @@ -1028,6 +1079,20 @@ lcp_rejci(f, p, len) try.neg = 0; \ LCPDEBUG((LOG_INFO,"lcp_rejci rejected LQR opt %d", opt)); \ } +#define REJCICBCP(opt, neg, val) \ + if (go->neg && \ + len >= CILEN_CBCP && \ + p[1] == CILEN_CBCP && \ + p[0] == opt) { \ + len -= CILEN_CBCP; \ + INCPTR(2, p); \ + GETCHAR(cichar, p); \ + /* Check rejected value. */ \ + 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); REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap); @@ -1036,6 +1101,7 @@ lcp_rejci(f, p, len) REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP); } REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period); + REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT); REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber); REJCIVOID(CI_PCOMPRESSION, neg_pcompression); REJCIVOID(CI_ACCOMPRESSION, neg_accompression); @@ -1501,7 +1567,6 @@ lcp_printpkt(p, plen, printer, arg) u_char *pstart, *optend; u_short cishort; u_int32_t cilong; - int fascii; if (plen < HEADERLEN) return 0; @@ -1580,6 +1645,20 @@ lcp_printpkt(p, plen, printer, arg) } } 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; @@ -1668,7 +1747,7 @@ LcpEchoCheck (f) * Start the timer for the next interval. */ assert (lcp_echo_timer_running==0); - TIMEOUT (LcpEchoTimeout, (caddr_t) f, lcp_echo_interval); + TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval); lcp_echo_timer_running = 1; } @@ -1678,7 +1757,7 @@ LcpEchoCheck (f) static void LcpEchoTimeout (arg) - caddr_t arg; + void *arg; { if (lcp_echo_timer_running != 0) { lcp_echo_timer_running = 0; @@ -1776,7 +1855,7 @@ lcp_echo_lowerdown (unit) fsm *f = &lcp_fsm[unit]; if (lcp_echo_timer_running != 0) { - UNTIMEOUT (LcpEchoTimeout, (caddr_t) f); + UNTIMEOUT (LcpEchoTimeout, f); lcp_echo_timer_running = 0; } }