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.
This commit is contained in:
Brian Somers 1998-05-15 18:21:12 +00:00
parent a36e970919
commit 0a1b5c9d9e
8 changed files with 100 additions and 53 deletions

View File

@ -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);

View File

@ -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 <sys/types.h>
@ -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;
}

View File

@ -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 <sys/types.h>
@ -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 *

View File

@ -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 <sys/types.h>
@ -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);

View File

@ -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++;

View File

@ -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

View File

@ -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 <sys/types.h>
@ -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

View File

@ -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