From 0a1b5c9d9ea926382e954159457256df082cf0be Mon Sep 17 00:00:00 2001 From: Brian Somers Date: Fri, 15 May 1998 18:21:12 +0000 Subject: [PATCH] o Activate link-level CCPs in multilink mode, by bringing them into the ST_STOPPED state. o Allow an optional ccp|lcp argument to `down'. The default is still lcp (as before). You can now call down with no context in multilink mode, in which case it'll down the multilink ccp or the entire bundle (*very* rude). o Allow an optional `!' after `close ccp' (close ccp!) to tell ccp to stay in the CLOSED state after the terminate ACK. The default is now to re-enter STOPPED so that the peer can bring the layer back up if desired. o Always handle proto-compressed packets, even if we've agreed (in LCP) that the peer will not send us 1 byte protocols. If the peer violates the LCP agreement, log it to the HDLC log. o Fix some comments. --- usr.sbin/ppp/ccp.c | 12 ++++++----- usr.sbin/ppp/command.c | 42 ++++++++++++++++++++++++++++++------- usr.sbin/ppp/datalink.c | 11 ++++++---- usr.sbin/ppp/deflate.c | 5 ++--- usr.sbin/ppp/hdlc.c | 46 ++++++++++++++++++++--------------------- usr.sbin/ppp/lcpproto.h | 4 +++- usr.sbin/ppp/mp.c | 7 +++++-- usr.sbin/ppp/ppp.8 | 26 ++++++++++++++++------- 8 files changed, 100 insertions(+), 53 deletions(-) diff --git a/usr.sbin/ppp/ccp.c b/usr.sbin/ppp/ccp.c index a672a94e28db..9abdf826bf02 100644 --- a/usr.sbin/ppp/ccp.c +++ b/usr.sbin/ppp/ccp.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: ccp.c,v 1.30.2.41 1998/04/30 23:53:23 brian Exp $ + * $Id: ccp.c,v 1.30.2.42 1998/05/01 19:23:57 brian Exp $ * * TODO: * o Support other compression protocols @@ -540,9 +540,11 @@ int ccp_Compress(struct ccp *ccp, struct link *l, int pri, u_short proto, struct mbuf *m) { - /* Compress outgoing Network Layer data */ - if ((proto & 0xfff1) == 0x21 && ccp->fsm.state == ST_OPENED && - ccp->out.state != NULL) + /* + * Compress outgoing data. It's already deemed to be suitable Network + * Layer data. + */ + if (ccp->fsm.state == ST_OPENED && ccp->out.state != NULL) return (*algorithm[ccp->out.algorithm]->o.Write) (ccp->out.state, ccp, l, pri, proto, m); return 0; @@ -566,7 +568,7 @@ ccp_Decompress(struct ccp *ccp, u_short *proto, struct mbuf *bp) (ccp->in.state, ccp, proto, bp); mbuf_Free(bp); bp = NULL; - } else if ((*proto & 0xfff1) == 0x21 && ccp->in.state != NULL) + } else if (PROTO_COMPRESSIBLE(*proto) && ccp->in.state != NULL) /* Add incoming Network Layer traffic to our dictionary */ (*algorithm[ccp->in.algorithm]->i.DictSetup) (ccp->in.state, ccp, *proto, bp); diff --git a/usr.sbin/ppp/command.c b/usr.sbin/ppp/command.c index 500147e847eb..2cfb9312a443 100644 --- a/usr.sbin/ppp/command.c +++ b/usr.sbin/ppp/command.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: command.c,v 1.131.2.81 1998/05/08 18:50:14 brian Exp $ + * $Id: command.c,v 1.131.2.82 1998/05/10 09:26:17 brian Exp $ * */ #include @@ -123,7 +123,7 @@ #define NEG_DNS 50 const char Version[] = "2.0-beta"; -const char VersionDate[] = "$Date: 1998/05/08 18:50:14 $"; +const char VersionDate[] = "$Date: 1998/05/10 09:26:17 $"; static int ShowCommand(struct cmdargs const *); static int TerminalCommand(struct cmdargs const *); @@ -431,7 +431,7 @@ static struct cmdtab const Commands[] = { "Dial and login", "dial|call [remote]"}, {"disable", NULL, NegotiateCommand, LOCAL_AUTH | LOCAL_CX_OPT, "Disable option", "disable option .."}, - {"down", NULL, DownCommand, LOCAL_AUTH | LOCAL_CX, + {"down", NULL, DownCommand, LOCAL_AUTH | LOCAL_CX_OPT, "Generate a down event", "down"}, {"enable", NULL, NegotiateCommand, LOCAL_AUTH | LOCAL_CX_OPT, "Enable option", "enable option .."}, @@ -810,8 +810,14 @@ OpenCommand(struct cmdargs const *arg) if (fp->link->lcp.fsm.state != ST_OPENED) log_Printf(LogWARN, "open: LCP must be open before opening CCP\n"); else if (fp->state != ST_OPENED) { - fsm_Up(fp); - fsm_Open(fp); + fp->open_mode = 0; /* Not passive any more */ + if (fp->state == ST_STOPPED) { + fsm_Down(fp); + fsm_Up(fp); + } else { + fsm_Up(fp); + fsm_Open(fp); + } } } else return -1; @@ -826,11 +832,17 @@ CloseCommand(struct cmdargs const *arg) (arg->argc == arg->argn+1 && !strcasecmp(arg->argv[arg->argn], "lcp"))) bundle_Close(arg->bundle, arg->cx ? arg->cx->name : NULL, 1); else if (arg->argc == arg->argn+1 && - !strcasecmp(arg->argv[arg->argn], "ccp")) { + (!strcasecmp(arg->argv[arg->argn], "ccp") || + !strcasecmp(arg->argv[arg->argn], "ccp!"))) { struct fsm *fp = &command_ChooseLink(arg)->ccp.fsm; - if (fp->state == ST_OPENED) + if (fp->state == ST_OPENED) { fsm_Close(fp); + if (arg->argv[arg->argn][3] == '!') + fp->open_mode = 0; /* Stay ST_CLOSED */ + else + fp->open_mode = OPEN_PASSIVE; /* Wait for the peer to start */ + } } else return -1; @@ -840,7 +852,21 @@ CloseCommand(struct cmdargs const *arg) static int DownCommand(struct cmdargs const *arg) { - datalink_Down(arg->cx, 1); + if (arg->argc == arg->argn || + (arg->argc == arg->argn+1 && !strcasecmp(arg->argv[arg->argn], "lcp"))) { + if (arg->cx) + datalink_Down(arg->cx, 1); + else + bundle_Down(arg->bundle); + } else if (arg->argc == arg->argn+1 && + !strcasecmp(arg->argv[arg->argn], "ccp")) { + struct fsm *fp = arg->cx ? &arg->cx->physical->link.ccp.fsm : + &arg->bundle->ncp.mp.link.ccp.fsm; + fsm_Down(fp); + fsm_Close(fp); + } else + return -1; + return 0; } diff --git a/usr.sbin/ppp/datalink.c b/usr.sbin/ppp/datalink.c index de8e8c52859a..286aaec45f50 100644 --- a/usr.sbin/ppp/datalink.c +++ b/usr.sbin/ppp/datalink.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: datalink.c,v 1.1.2.58 1998/05/09 13:52:12 brian Exp $ + * $Id: datalink.c,v 1.1.2.59 1998/05/11 23:39:29 brian Exp $ */ #include @@ -456,10 +456,12 @@ datalink_AuthOk(struct datalink *dl) /* We've handed the link off to another ppp ! */ return; case MP_UP: + /* First link in the bundle */ auth_Select(dl->bundle, dl->peer.authname, dl->physical); - break; + /* fall through */ case MP_ADDED: - /* We were already in multilink mode ! */ + /* We're in multilink mode ! */ + dl->physical->link.ccp.fsm.open_mode = OPEN_PASSIVE; break; case MP_FAILED: datalink_AuthNotOk(dl); @@ -522,7 +524,8 @@ datalink_LayerFinish(void *v, struct fsm *fp) fsm_Down(fp); /* Bring us to INITIAL or STARTING */ (*dl->parent->LayerFinish)(dl->parent->object, fp); datalink_ComeDown(dl, 0); - } + } else if (fp->state == ST_CLOSED && fp->open_mode == OPEN_PASSIVE) + fsm_Open(fp); /* CCP goes to ST_STOPPED */ } struct datalink * diff --git a/usr.sbin/ppp/deflate.c b/usr.sbin/ppp/deflate.c index 4bd9a9180979..252a39688ca5 100644 --- a/usr.sbin/ppp/deflate.c +++ b/usr.sbin/ppp/deflate.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: deflate.c,v 1.6.4.14 1998/04/25 10:48:56 brian Exp $ + * $Id: deflate.c,v 1.6.4.15 1998/05/01 19:24:25 brian Exp $ */ #include @@ -147,8 +147,7 @@ DeflateOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short proto, /* * If the output packet (including seqno and excluding the EMPTY_BLOCK) - * got bigger, send the original - returning 0 to hdlc_Output() will - * continue to send ``mp''. + * got bigger, send the original. */ if (olen >= ilen) { mbuf_Free(mo_head); diff --git a/usr.sbin/ppp/hdlc.c b/usr.sbin/ppp/hdlc.c index 3bc2a8f657cd..a7b9fc02e551 100644 --- a/usr.sbin/ppp/hdlc.c +++ b/usr.sbin/ppp/hdlc.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: hdlc.c,v 1.28.2.34 1998/05/08 01:15:07 brian Exp $ + * $Id: hdlc.c,v 1.28.2.35 1998/05/11 23:39:30 brian Exp $ * * TODO: */ @@ -454,11 +454,23 @@ hdlc_DecodePacket(struct bundle *bundle, u_short proto, struct mbuf * bp, } } +static int +hdlc_GetProto(const u_char *cp, u_short *proto) +{ + *proto = *cp; + if (!(*proto & 1)) { + *proto = (*proto << 8) | cp[1]; + return 2; + } + return 1; +} + void hdlc_Input(struct bundle *bundle, struct mbuf * bp, struct physical *physical) { u_short fcs, proto; u_char *cp, addr, ctrl; + int n; log_DumpBp(LogHDLC, "hdlc_Input:", bp); if (physical_IsSync(physical)) @@ -485,9 +497,7 @@ hdlc_Input(struct bundle *bundle, struct mbuf * bp, struct physical *physical) cp = MBUF_CTOP(bp); if (!physical->link.lcp.want_acfcomp) { - /* - * We expect that packet is not compressed. - */ + /* We expect the packet not to be compressed */ addr = *cp++; if (addr != HDLC_ADDR) { physical->hdlc.lqm.SaveInErrors++; @@ -507,31 +517,21 @@ hdlc_Input(struct bundle *bundle, struct mbuf * bp, struct physical *physical) bp->offset += 2; bp->cnt -= 2; } else if (cp[0] == HDLC_ADDR && cp[1] == HDLC_UI) { - /* - * We can receive compressed packet, but peer still send uncompressed - * packet to me. + * We can receive compressed packets, but the peer still sends + * uncompressed packets ! */ cp += 2; bp->offset += 2; bp->cnt -= 2; } - if (physical->link.lcp.want_protocomp) { - proto = 0; - cp--; - do { - cp++; - bp->offset++; - bp->cnt--; - proto = proto << 8; - proto += *cp; - } while (!(proto & 1)); - } else { - proto = *cp++ << 8; - proto |= *cp++; - bp->offset += 2; - bp->cnt -= 2; - } + + n = hdlc_GetProto(cp, &proto); + bp->offset += n; + bp->cnt -= n; + if (!physical->link.lcp.want_protocomp && n == 1) + log_Printf(LogHDLC, "%s: Warning: received a proto-compressed packet !\n", + physical->link.name); link_ProtocolRecord(&physical->link, proto, PROTO_IN); physical->hdlc.lqm.SaveInPackets++; diff --git a/usr.sbin/ppp/lcpproto.h b/usr.sbin/ppp/lcpproto.h index 276d8a126826..6b7e32659f7f 100644 --- a/usr.sbin/ppp/lcpproto.h +++ b/usr.sbin/ppp/lcpproto.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: lcpproto.h,v 1.10 1997/10/26 12:42:12 brian Exp $ + * $Id: lcpproto.h,v 1.10.2.1 1998/04/03 19:21:31 brian Exp $ * * TODO: */ @@ -30,6 +30,8 @@ #define PROTO_ICOMPD 0x00fb /* Individual link compressed */ #define PROTO_COMPD 0x00fd /* Compressed datagram */ +#define PROTO_COMPRESSIBLE(p) (((p) & 0xffe1) == 0x21) + #define PROTO_IPCP 0x8021 #define PROTO_ICCP 0x80fb #define PROTO_CCP 0x80fd diff --git a/usr.sbin/ppp/mp.c b/usr.sbin/ppp/mp.c index e792104a88bc..570f5f143495 100644 --- a/usr.sbin/ppp/mp.c +++ b/usr.sbin/ppp/mp.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp.c,v 1.1.2.26 1998/05/08 01:15:16 brian Exp $ + * $Id: mp.c,v 1.1.2.27 1998/05/10 22:20:11 brian Exp $ */ #include @@ -167,6 +167,8 @@ static void mp_LayerFinish(void *v, struct fsm *fp) { /* The given fsm (ccp) is now down */ + if (fp->state == ST_CLOSED && fp->open_mode == OPEN_PASSIVE) + fsm_Open(fp); /* CCP goes to ST_STOPPED */ } void @@ -526,7 +528,8 @@ mp_Output(struct mp *mp, struct link *l, struct mbuf *m, u_int32_t begin, mp->out.seq, mbuf_Length(mo), l->name); mp->out.seq = inc_seq(mp->peer_is12bit, mp->out.seq); - hdlc_Output(l, PRI_NORMAL, PROTO_MP, mo); + if (!ccp_Compress(&l->ccp, l, PRI_NORMAL, PROTO_MP, mo)) + hdlc_Output(l, PRI_NORMAL, PROTO_MP, mo); } int diff --git a/usr.sbin/ppp/ppp.8 b/usr.sbin/ppp/ppp.8 index a7c707afb5f2..493211f7423f 100644 --- a/usr.sbin/ppp/ppp.8 +++ b/usr.sbin/ppp/ppp.8 @@ -1,4 +1,4 @@ -.\" $Id: ppp.8,v 1.97.2.31 1998/05/10 09:26:21 brian Exp $ +.\" $Id: ppp.8,v 1.97.2.32 1998/05/13 19:06:27 brian Exp $ .Dd 20 September 1995 .Os FreeBSD .Dt PPP 8 @@ -2130,13 +2130,21 @@ command below. .Pp The default link name is .Dq deflink . -.It close Op lcp|ccp +.It close Op lcp|ccp[!] If no arguments are given, or if .Dq lcp is specified, the link will be closed. If .Dq ccp -is specified, only the relevent compression layer is closed. Either way, -this command does not disconnect the user from ppp or exit ppp. See the +is specified, only the relevent compression layer is closed. If the +.Dq \&! +is used, the compression layer will remain in the closed state, otherwise +it will re-enter the STOPPED state, waiting for the peer to initiate +further CCP negotiation. In any event, this command does not disconnect +the user from +.Nm +or exit +.Nm ppp . +See the .Dq quit command below. .It delete[!] Ar dest @@ -2172,9 +2180,13 @@ scripts for the given .Ar label . Otherwise, the current settings are used to establish the connection. -.It down -Bring the link down ungracefully, as if the physical layer had become -unavailable. It's not considered polite to use this command. +.It down Op Ar lcp|ccp +Bring the relevent layer down ungracefully, as if the underlying layer +had become unavailable. It's not considered polite to use this command on +a Finite State Machine that's in the OPEN state. If no arguments are +supplied, +.Sq lcp +is assumed. .It help|? Op Ar command Show a list of available commands. If .Ar command