mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-21 09:13:37 +00:00
Make all CCP negotiation data dynamic and add a
``set deflate'' command to configure the DEFLATE default window size.
This commit is contained in:
parent
fd33683210
commit
03036ec70d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/MP/; revision=34648
|
@ -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.22 1998/03/16 22:51:49 brian Exp $
|
||||
* $Id: ccp.c,v 1.30.2.23 1998/03/16 22:53:31 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
* o Support other compression protocols
|
||||
|
@ -28,6 +28,7 @@
|
|||
#include <netinet/ip.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
|
@ -150,6 +151,8 @@ ccp_Init(struct ccp *ccp, struct bundle *bundle, struct link *l,
|
|||
/* Initialise ourselves */
|
||||
fsm_Init(&ccp->fsm, "CCP", PROTO_CCP, CCP_MAXCODE, 10, LogCCP,
|
||||
bundle, l, parent, &ccp_Callbacks);
|
||||
ccp->cfg.deflate.in.winsize = 0;
|
||||
ccp->cfg.deflate.out.winsize = 15;
|
||||
ccp_Setup(ccp);
|
||||
}
|
||||
|
||||
|
@ -161,9 +164,11 @@ ccp_Setup(struct ccp *ccp)
|
|||
ccp->fsm.maxconfig = 10;
|
||||
ccp->his_proto = ccp->my_proto = -1;
|
||||
ccp->reset_sent = ccp->last_reset = -1;
|
||||
ccp->in_algorithm = ccp->out_algorithm = -1;
|
||||
ccp->in.algorithm = ccp->out.algorithm = -1;
|
||||
ccp->in.state = ccp->out.state = NULL;
|
||||
ccp->in.opt.id = -1;
|
||||
ccp->out.opt = NULL;
|
||||
ccp->his_reject = ccp->my_reject = 0;
|
||||
ccp->out_init = ccp->in_init = 0;
|
||||
ccp->uncompout = ccp->compout = 0;
|
||||
ccp->uncompin = ccp->compin = 0;
|
||||
}
|
||||
|
@ -181,26 +186,47 @@ CcpSendConfigReq(struct fsm *fp)
|
|||
{
|
||||
/* Send config REQ please */
|
||||
struct ccp *ccp = fsm2ccp(fp);
|
||||
struct ccp_opt **o;
|
||||
u_char *cp, buff[100];
|
||||
int f;
|
||||
int f, alloc;
|
||||
|
||||
LogPrintf(LogCCP, "CcpSendConfigReq\n");
|
||||
cp = buff;
|
||||
o = &ccp->out.opt;
|
||||
alloc = ccp->his_reject == 0 && ccp->out.opt == NULL;
|
||||
ccp->my_proto = -1;
|
||||
ccp->out_algorithm = -1;
|
||||
ccp->out.algorithm = -1;
|
||||
for (f = 0; f < NALGORITHMS; f++)
|
||||
if (Enabled(algorithm[f]->Conf) && !REJECTED(ccp, algorithm[f]->id)) {
|
||||
struct lcp_opt o;
|
||||
if (alloc) {
|
||||
*o = (struct ccp_opt *)malloc(sizeof(struct ccp_opt));
|
||||
(*o)->val.id = algorithm[f]->id;
|
||||
(*o)->val.len = 2;
|
||||
(*o)->next = NULL;
|
||||
(*o)->algorithm = f;
|
||||
(*algorithm[f]->o.OptInit)(&(*o)->val, &ccp->cfg);
|
||||
} else {
|
||||
for (o = &ccp->out.opt; *o != NULL; o = &(*o)->next)
|
||||
if ((*o)->val.id == algorithm[f]->id && (*o)->algorithm == f)
|
||||
break;
|
||||
if (*o == NULL) {
|
||||
LogPrintf(LogERROR, "CCP REQ buffer lost !\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
(*algorithm[f]->o.Get)(&o);
|
||||
if (cp + o.len > buff + sizeof buff) {
|
||||
if (cp + (*o)->val.len > buff + sizeof buff) {
|
||||
LogPrintf(LogERROR, "CCP REQ buffer overrun !\n");
|
||||
break;
|
||||
}
|
||||
cp += LcpPutConf(LogCCP, cp, &o, cftypes[o.id],
|
||||
(*algorithm[f]->Disp)(&o));
|
||||
ccp->my_proto = o.id;
|
||||
ccp->out_algorithm = f;
|
||||
cp += LcpPutConf(LogCCP, cp, &(*o)->val, cftypes[(*o)->val.id],
|
||||
(*algorithm[f]->Disp)(&(*o)->val));
|
||||
|
||||
ccp->my_proto = (*o)->val.id;
|
||||
ccp->out.algorithm = f;
|
||||
|
||||
if (alloc)
|
||||
o = &(*o)->next;
|
||||
}
|
||||
FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, buff, cp - buff);
|
||||
}
|
||||
|
@ -235,8 +261,8 @@ CcpRecvResetReq(struct fsm *fp)
|
|||
{
|
||||
/* Got a reset REQ, reset outgoing dictionary */
|
||||
struct ccp *ccp = fsm2ccp(fp);
|
||||
if (ccp->out_init)
|
||||
(*algorithm[ccp->out_algorithm]->o.Reset)();
|
||||
if (ccp->out.state != NULL)
|
||||
(*algorithm[ccp->out.algorithm]->o.Reset)(ccp->out.state);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -252,13 +278,13 @@ CcpLayerFinish(struct fsm *fp)
|
|||
/* We're now down */
|
||||
struct ccp *ccp = fsm2ccp(fp);
|
||||
LogPrintf(LogCCP, "CcpLayerFinish.\n");
|
||||
if (ccp->in_init) {
|
||||
(*algorithm[ccp->in_algorithm]->i.Term)();
|
||||
ccp->in_init = 0;
|
||||
if (ccp->in.state != NULL) {
|
||||
(*algorithm[ccp->in.algorithm]->i.Term)(ccp->in.state);
|
||||
ccp->in.state = NULL;
|
||||
}
|
||||
if (ccp->out_init) {
|
||||
(*algorithm[ccp->out_algorithm]->o.Term)();
|
||||
ccp->out_init = 0;
|
||||
if (ccp->out.state != NULL) {
|
||||
(*algorithm[ccp->out.algorithm]->o.Term)(ccp->out.state);
|
||||
ccp->out.state = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,26 +304,29 @@ CcpLayerUp(struct fsm *fp)
|
|||
/* We're now up */
|
||||
struct ccp *ccp = fsm2ccp(fp);
|
||||
LogPrintf(LogCCP, "CcpLayerUp.\n");
|
||||
if (!ccp->in_init && ccp->in_algorithm >= 0 &&
|
||||
ccp->in_algorithm < NALGORITHMS)
|
||||
if ((*algorithm[ccp->in_algorithm]->i.Init)())
|
||||
ccp->in_init = 1;
|
||||
else {
|
||||
if (ccp->in.state == NULL && ccp->in.algorithm >= 0 &&
|
||||
ccp->in.algorithm < NALGORITHMS) {
|
||||
ccp->in.state = (*algorithm[ccp->in.algorithm]->i.Init)(&ccp->in.opt);
|
||||
if (ccp->in.state == NULL) {
|
||||
LogPrintf(LogERROR, "%s (in) initialisation failure\n",
|
||||
protoname(ccp->his_proto));
|
||||
ccp->his_proto = ccp->my_proto = -1;
|
||||
FsmClose(fp);
|
||||
}
|
||||
if (!ccp->out_init && ccp->out_algorithm >= 0 &&
|
||||
ccp->out_algorithm < NALGORITHMS)
|
||||
if ((*algorithm[ccp->out_algorithm]->o.Init)())
|
||||
ccp->out_init = 1;
|
||||
else {
|
||||
}
|
||||
|
||||
if (ccp->out.state == NULL && ccp->out.algorithm >= 0 &&
|
||||
ccp->out.algorithm < NALGORITHMS) {
|
||||
ccp->out.state = (*algorithm[ccp->out.algorithm]->o.Init)
|
||||
(&ccp->out.opt->val);
|
||||
if (ccp->out.state == NULL) {
|
||||
LogPrintf(LogERROR, "%s (out) initialisation failure\n",
|
||||
protoname(ccp->my_proto));
|
||||
ccp->his_proto = ccp->my_proto = -1;
|
||||
FsmClose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
LogPrintf(LogCCP, "Out = %s[%d], In = %s[%d]\n",
|
||||
protoname(ccp->my_proto), ccp->my_proto,
|
||||
protoname(ccp->his_proto), ccp->his_proto);
|
||||
|
@ -311,19 +340,30 @@ CcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
|
|||
struct ccp *ccp = fsm2ccp(fp);
|
||||
int type, length;
|
||||
int f;
|
||||
const char *end;
|
||||
|
||||
while (plen >= sizeof(struct fsmconfig)) {
|
||||
type = *cp;
|
||||
length = cp[1];
|
||||
if (type < NCFTYPES)
|
||||
LogPrintf(LogCCP, " %s[%d]\n", cftypes[type], length);
|
||||
else
|
||||
LogPrintf(LogCCP, " ???[%d]\n", length);
|
||||
|
||||
if (length > sizeof(struct lcp_opt)) {
|
||||
length = sizeof(struct lcp_opt);
|
||||
LogPrintf(LogCCP, "Warning: Truncating length to %d\n", length);
|
||||
}
|
||||
|
||||
for (f = NALGORITHMS-1; f > -1; f--)
|
||||
if (algorithm[f]->id == type)
|
||||
break;
|
||||
|
||||
end = f == -1 ? "" : (*algorithm[f]->Disp)((struct lcp_opt *)cp);
|
||||
if (end == NULL)
|
||||
end = "";
|
||||
|
||||
if (type < NCFTYPES)
|
||||
LogPrintf(LogCCP, " %s[%d] %s\n", cftypes[type], length, end);
|
||||
else
|
||||
LogPrintf(LogCCP, " ???[%d] %s\n", length, end);
|
||||
|
||||
if (f == -1) {
|
||||
/* Don't understand that :-( */
|
||||
if (mode_type == MODE_REQ) {
|
||||
|
@ -332,26 +372,26 @@ CcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
|
|||
dec->rejend += length;
|
||||
}
|
||||
} else {
|
||||
struct lcp_opt o;
|
||||
struct ccp_opt *o;
|
||||
|
||||
switch (mode_type) {
|
||||
case MODE_REQ:
|
||||
if (Acceptable(algorithm[f]->Conf) && ccp->in_algorithm == -1) {
|
||||
memcpy(&o, cp, length);
|
||||
switch ((*algorithm[f]->i.Set)(&o)) {
|
||||
if (Acceptable(algorithm[f]->Conf) && ccp->in.algorithm == -1) {
|
||||
memcpy(&ccp->in.opt, cp, length);
|
||||
switch ((*algorithm[f]->i.Set)(&ccp->in.opt, &ccp->cfg)) {
|
||||
case MODE_REJ:
|
||||
memcpy(dec->rejend, &o, o.len);
|
||||
dec->rejend += o.len;
|
||||
memcpy(dec->rejend, &ccp->in.opt, ccp->in.opt.len);
|
||||
dec->rejend += ccp->in.opt.len;
|
||||
break;
|
||||
case MODE_NAK:
|
||||
memcpy(dec->nakend, &o, o.len);
|
||||
dec->nakend += o.len;
|
||||
memcpy(dec->nakend, &ccp->in.opt, ccp->in.opt.len);
|
||||
dec->nakend += ccp->in.opt.len;
|
||||
break;
|
||||
case MODE_ACK:
|
||||
memcpy(dec->ackend, cp, length);
|
||||
dec->ackend += length;
|
||||
ccp->his_proto = type;
|
||||
ccp->in_algorithm = f; /* This one'll do ! */
|
||||
ccp->in.algorithm = f; /* This one'll do :-) */
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
@ -360,12 +400,19 @@ CcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
|
|||
}
|
||||
break;
|
||||
case MODE_NAK:
|
||||
memcpy(&o, cp, length);
|
||||
if ((*algorithm[f]->o.Set)(&o) == MODE_ACK)
|
||||
ccp->my_proto = algorithm[f]->id;
|
||||
for (o = ccp->out.opt; o != NULL; o = o->next)
|
||||
if (o->val.id == cp[0])
|
||||
break;
|
||||
if (o == NULL)
|
||||
LogPrintf(LogCCP, "Warning: Ignoring peer NAK of unsent option\n");
|
||||
else {
|
||||
ccp->his_reject |= (1 << type);
|
||||
ccp->my_proto = -1;
|
||||
memcpy(&o->val, cp, length);
|
||||
if ((*algorithm[f]->o.Set)(&o->val) == MODE_ACK)
|
||||
ccp->my_proto = algorithm[f]->id;
|
||||
else {
|
||||
ccp->his_reject |= (1 << type);
|
||||
ccp->my_proto = -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MODE_REJ:
|
||||
|
@ -375,15 +422,24 @@ CcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
|
|||
}
|
||||
}
|
||||
|
||||
plen -= length;
|
||||
cp += length;
|
||||
plen -= cp[1];
|
||||
cp += cp[1];
|
||||
}
|
||||
|
||||
if (mode_type != MODE_NOP && dec->rejend != dec->rej) {
|
||||
dec->ackend = dec->ack; /* let's not send both ! */
|
||||
if (!ccp->in_init) {
|
||||
/* rejects are preferred */
|
||||
dec->ackend = dec->ack;
|
||||
dec->nakend = dec->nak;
|
||||
if (ccp->in.state == NULL) {
|
||||
ccp->his_proto = -1;
|
||||
ccp->in_algorithm = -1;
|
||||
ccp->in.algorithm = -1;
|
||||
}
|
||||
} else if (mode_type != MODE_NOP && dec->nakend != dec->nak) {
|
||||
/* then NAKs */
|
||||
dec->ackend = dec->ack;
|
||||
if (ccp->in.state == NULL) {
|
||||
ccp->his_proto = -1;
|
||||
ccp->in.algorithm = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -423,8 +479,8 @@ CcpRecvResetAck(struct fsm *fp, u_char id)
|
|||
|
||||
ccp->last_reset = ccp->reset_sent;
|
||||
ccp->reset_sent = -1;
|
||||
if (ccp->in_init)
|
||||
(*algorithm[ccp->in_algorithm]->i.Reset)();
|
||||
if (ccp->in.state != NULL)
|
||||
(*algorithm[ccp->in.algorithm]->i.Reset)(ccp->in.state);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -432,8 +488,10 @@ ccp_Output(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_init)
|
||||
return (*algorithm[ccp->out_algorithm]->o.Write)(ccp, l, pri, proto, m);
|
||||
if ((proto & 0xfff1) == 0x21 && 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;
|
||||
}
|
||||
|
||||
|
@ -451,13 +509,15 @@ ccp_Decompress(struct ccp *ccp, u_short *proto, struct mbuf *bp)
|
|||
/* Send another REQ and put the packet in the bit bucket */
|
||||
LogPrintf(LogCCP, "ReSendResetReq(%d)\n", ccp->reset_sent);
|
||||
FsmOutput(&ccp->fsm, CODE_RESETREQ, ccp->reset_sent, NULL, 0);
|
||||
} else if (ccp->in_init)
|
||||
return (*algorithm[ccp->in_algorithm]->i.Read)(ccp, proto, bp);
|
||||
} else if (ccp->in.state != NULL)
|
||||
return (*algorithm[ccp->in.algorithm]->i.Read)
|
||||
(ccp->in.state, ccp, proto, bp);
|
||||
pfree(bp);
|
||||
bp = NULL;
|
||||
} else if ((*proto & 0xfff1) == 0x21 && ccp->in_init)
|
||||
} else if ((*proto & 0xfff1) == 0x21 && ccp->in.state != NULL)
|
||||
/* Add incoming Network Layer traffic to our dictionary */
|
||||
(*algorithm[ccp->in_algorithm]->i.DictSetup)(ccp, *proto, bp);
|
||||
(*algorithm[ccp->in.algorithm]->i.DictSetup)
|
||||
(ccp->in.state, ccp, *proto, bp);
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: ccp.h,v 1.14.2.11 1998/02/23 00:38:19 brian Exp $
|
||||
* $Id: ccp.h,v 1.14.2.12 1998/02/27 01:22:19 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
@ -35,6 +35,20 @@
|
|||
#define TY_PPPD_DEFLATE 24 /* Deflate (gzip) - (mis) numbered by pppd */
|
||||
#define TY_DEFLATE 26 /* Deflate (gzip) - rfc 1979 */
|
||||
|
||||
struct ccp_config {
|
||||
struct {
|
||||
struct {
|
||||
int winsize;
|
||||
} in, out;
|
||||
} deflate;
|
||||
};
|
||||
|
||||
struct ccp_opt {
|
||||
struct ccp_opt *next;
|
||||
int algorithm;
|
||||
struct lcp_opt val;
|
||||
};
|
||||
|
||||
struct ccp {
|
||||
struct fsm fsm; /* The finite state machine */
|
||||
|
||||
|
@ -44,17 +58,25 @@ struct ccp {
|
|||
int reset_sent; /* If != -1, ignore compressed 'till ack */
|
||||
int last_reset; /* We can receive more (dups) w/ this id */
|
||||
|
||||
int in_algorithm; /* Incoming algorithm in use */
|
||||
int out_algorithm; /* Outgoing algorithm in use */
|
||||
struct {
|
||||
int algorithm; /* Algorithm in use */
|
||||
void *state; /* Returned by implementations Init() */
|
||||
struct lcp_opt opt; /* Set by implementations OptInit() */
|
||||
} in;
|
||||
|
||||
struct {
|
||||
int algorithm; /* Algorithm in use */
|
||||
void *state; /* Returned by implementations Init() */
|
||||
struct ccp_opt *opt; /* Set by implementations OptInit() */
|
||||
} out;
|
||||
|
||||
u_int32_t his_reject; /* Request codes rejected by peer */
|
||||
u_int32_t my_reject; /* Request codes I have rejected */
|
||||
|
||||
int out_init : 1; /* Init called for out algorithm */
|
||||
int in_init : 1; /* Init called for in algorithm */
|
||||
|
||||
u_long uncompout, compout;
|
||||
u_long uncompin, compin;
|
||||
|
||||
struct ccp_config cfg;
|
||||
};
|
||||
|
||||
#define fsm2ccp(fp) (fp->proto == PROTO_CCP ? (struct ccp *)fp : NULL)
|
||||
|
@ -64,21 +86,21 @@ struct ccp_algorithm {
|
|||
int Conf; /* A Conf value from vars.h */
|
||||
const char *(*Disp)(struct lcp_opt *);
|
||||
struct {
|
||||
void (*Get)(struct lcp_opt *);
|
||||
int (*Set)(struct lcp_opt *);
|
||||
int (*Init)(void);
|
||||
void (*Term)(void);
|
||||
void (*Reset)(void);
|
||||
struct mbuf *(*Read)(struct ccp *, u_short *, struct mbuf *);
|
||||
void (*DictSetup)(struct ccp *, u_short, struct mbuf *);
|
||||
int (*Set)(struct lcp_opt *, const struct ccp_config *);
|
||||
void *(*Init)(struct lcp_opt *);
|
||||
void (*Term)(void *);
|
||||
void (*Reset)(void *);
|
||||
struct mbuf *(*Read)(void *, struct ccp *, u_short *, struct mbuf *);
|
||||
void (*DictSetup)(void *, struct ccp *, u_short, struct mbuf *);
|
||||
} i;
|
||||
struct {
|
||||
void (*Get)(struct lcp_opt *);
|
||||
void (*OptInit)(struct lcp_opt *, const struct ccp_config *);
|
||||
int (*Set)(struct lcp_opt *);
|
||||
int (*Init)(void);
|
||||
void (*Term)(void);
|
||||
void (*Reset)(void);
|
||||
int (*Write)(struct ccp *, struct link *, int, u_short, struct mbuf *);
|
||||
void *(*Init)(struct lcp_opt *);
|
||||
void (*Term)(void *);
|
||||
void (*Reset)(void *);
|
||||
int (*Write)(void *, struct ccp *, struct link *, int, u_short,
|
||||
struct mbuf *);
|
||||
} o;
|
||||
};
|
||||
|
||||
|
|
|
@ -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.39 1998/03/16 22:51:58 brian Exp $
|
||||
* $Id: command.c,v 1.131.2.40 1998/03/16 22:53:38 brian Exp $
|
||||
*
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
|
@ -1314,6 +1314,27 @@ SetVariable(struct cmdargs const *arg)
|
|||
cx->cfg.script.login[sizeof cx->cfg.script.login - 1] = '\0';
|
||||
}
|
||||
break;
|
||||
case VAR_WINSIZE:
|
||||
if (arg->argc > 0) {
|
||||
cx->ccp.cfg.deflate.out.winsize = atoi(arg->argv[0]);
|
||||
if (cx->ccp.cfg.deflate.out.winsize < 8 ||
|
||||
cx->ccp.cfg.deflate.out.winsize > 15) {
|
||||
LogPrintf(LogWARN, "%d: Invalid outgoing window size\n",
|
||||
cx->ccp.cfg.deflate.out.winsize);
|
||||
cx->ccp.cfg.deflate.out.winsize = 15;
|
||||
}
|
||||
if (arg->argc > 1) {
|
||||
cx->ccp.cfg.deflate.in.winsize = atoi(arg->argv[1]);
|
||||
if (cx->ccp.cfg.deflate.in.winsize < 8 ||
|
||||
cx->ccp.cfg.deflate.in.winsize > 15) {
|
||||
LogPrintf(LogWARN, "%d: Invalid incoming window size\n",
|
||||
cx->ccp.cfg.deflate.in.winsize);
|
||||
cx->ccp.cfg.deflate.in.winsize = 15;
|
||||
}
|
||||
} else
|
||||
cx->ccp.cfg.deflate.in.winsize = 0;
|
||||
}
|
||||
break;
|
||||
case VAR_DEVICE:
|
||||
Physical_SetDeviceList(cx->physical, argp);
|
||||
break;
|
||||
|
@ -1385,6 +1406,9 @@ static struct cmdtab const SetCommands[] = {
|
|||
"Set authentication name", "set authname name", (const void *) VAR_AUTHNAME},
|
||||
{"ctsrts", NULL, SetCtsRts, LOCAL_AUTH | LOCAL_CX,
|
||||
"Use CTS/RTS modem signalling", "set ctsrts [on|off]"},
|
||||
{"deflate", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX,
|
||||
"Set deflate window sizes", "set deflate out-winsize in-winsize",
|
||||
(const void *) VAR_WINSIZE},
|
||||
{"device", "line", SetVariable, LOCAL_AUTH | LOCAL_CX,
|
||||
"Set modem device name", "set device|line device-name[,device-name]",
|
||||
(const void *) VAR_DEVICE},
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: command.h,v 1.12.2.3 1998/02/10 03:23:11 brian Exp $
|
||||
* $Id: command.h,v 1.12.2.4 1998/02/17 19:27:54 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
@ -45,12 +45,13 @@ struct cmdtab {
|
|||
#define VAR_DIAL 1
|
||||
#define VAR_LOGIN 2
|
||||
#define VAR_AUTHNAME 3
|
||||
#define VAR_DEVICE 4
|
||||
#define VAR_ACCMAP 5
|
||||
#define VAR_PHONE 6
|
||||
#define VAR_HANGUP 7
|
||||
#define VAR_WINSIZE 4
|
||||
#define VAR_DEVICE 5
|
||||
#define VAR_ACCMAP 6
|
||||
#define VAR_PHONE 7
|
||||
#define VAR_HANGUP 8
|
||||
#ifdef HAVE_DES
|
||||
#define VAR_ENC 8
|
||||
#define VAR_ENC 9
|
||||
#endif
|
||||
|
||||
extern struct in_addr ifnetmask;
|
||||
|
|
|
@ -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.6 1998/02/23 00:38:28 brian Exp $
|
||||
* $Id: deflate.c,v 1.6.4.7 1998/03/13 00:44:00 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -54,30 +54,31 @@
|
|||
struct deflate_state {
|
||||
u_short seqno;
|
||||
int uncomp_rec;
|
||||
int winsize;
|
||||
z_stream cx;
|
||||
};
|
||||
|
||||
static int iWindowSize = 15;
|
||||
static int oWindowSize = 15;
|
||||
static struct deflate_state InputState, OutputState;
|
||||
static char garbage[10];
|
||||
static u_char EMPTY_BLOCK[4] = { 0x00, 0x00, 0xff, 0xff };
|
||||
|
||||
#define DEFLATE_CHUNK_LEN 1024 /* Allocate mbufs this size */
|
||||
|
||||
static void
|
||||
DeflateResetOutput(void)
|
||||
DeflateResetOutput(void *v)
|
||||
{
|
||||
OutputState.seqno = 0;
|
||||
OutputState.uncomp_rec = 0;
|
||||
deflateReset(&OutputState.cx);
|
||||
struct deflate_state *state = (struct deflate_state *)v;
|
||||
|
||||
state->seqno = 0;
|
||||
state->uncomp_rec = 0;
|
||||
deflateReset(&state->cx);
|
||||
LogPrintf(LogCCP, "Deflate: Output channel reset\n");
|
||||
}
|
||||
|
||||
static int
|
||||
DeflateOutput(struct ccp *ccp, struct link *l, int pri, u_short proto,
|
||||
DeflateOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short proto,
|
||||
struct mbuf *mp)
|
||||
{
|
||||
struct deflate_state *state = (struct deflate_state *)v;
|
||||
u_char *wp, *rp;
|
||||
int olen, ilen, len, res, flush;
|
||||
struct mbuf *mo_head, *mo, *mi_head, *mi;
|
||||
|
@ -103,53 +104,53 @@ DeflateOutput(struct ccp *ccp, struct link *l, int pri, u_short proto,
|
|||
mo_head = mo = mballoc(DEFLATE_CHUNK_LEN, MB_HDLCOUT);
|
||||
mo->cnt = 2;
|
||||
wp = MBUF_CTOP(mo);
|
||||
*wp++ = OutputState.seqno >> 8;
|
||||
*wp++ = OutputState.seqno & 0377;
|
||||
LogPrintf(LogDEBUG, "DeflateOutput: Seq %d\n", OutputState.seqno);
|
||||
OutputState.seqno++;
|
||||
*wp++ = state->seqno >> 8;
|
||||
*wp++ = state->seqno & 0377;
|
||||
LogPrintf(LogDEBUG, "DeflateOutput: Seq %d\n", state->seqno);
|
||||
state->seqno++;
|
||||
|
||||
/* Set up the deflation context */
|
||||
OutputState.cx.next_out = wp;
|
||||
OutputState.cx.avail_out = DEFLATE_CHUNK_LEN - 2;
|
||||
OutputState.cx.next_in = MBUF_CTOP(mi);
|
||||
OutputState.cx.avail_in = mi->cnt;
|
||||
state->cx.next_out = wp;
|
||||
state->cx.avail_out = DEFLATE_CHUNK_LEN - 2;
|
||||
state->cx.next_in = MBUF_CTOP(mi);
|
||||
state->cx.avail_in = mi->cnt;
|
||||
flush = Z_NO_FLUSH;
|
||||
|
||||
olen = 0;
|
||||
while (1) {
|
||||
if ((res = deflate(&OutputState.cx, flush)) != Z_OK) {
|
||||
if ((res = deflate(&state->cx, flush)) != Z_OK) {
|
||||
if (res == Z_STREAM_END)
|
||||
break; /* Done */
|
||||
LogPrintf(LogERROR, "DeflateOutput: deflate returned %d (%s)\n",
|
||||
res, OutputState.cx.msg ? OutputState.cx.msg : "");
|
||||
res, state->cx.msg ? state->cx.msg : "");
|
||||
pfree(mo_head);
|
||||
mbfree(mi_head);
|
||||
OutputState.seqno--;
|
||||
state->seqno--;
|
||||
return 1; /* packet dropped */
|
||||
}
|
||||
|
||||
if (flush == Z_SYNC_FLUSH && OutputState.cx.avail_out != 0)
|
||||
if (flush == Z_SYNC_FLUSH && state->cx.avail_out != 0)
|
||||
break;
|
||||
|
||||
if (OutputState.cx.avail_in == 0 && mi->next != NULL) {
|
||||
if (state->cx.avail_in == 0 && mi->next != NULL) {
|
||||
mi = mi->next;
|
||||
OutputState.cx.next_in = MBUF_CTOP(mi);
|
||||
OutputState.cx.avail_in = mi->cnt;
|
||||
state->cx.next_in = MBUF_CTOP(mi);
|
||||
state->cx.avail_in = mi->cnt;
|
||||
if (mi->next == NULL)
|
||||
flush = Z_SYNC_FLUSH;
|
||||
}
|
||||
|
||||
if (OutputState.cx.avail_out == 0) {
|
||||
if (state->cx.avail_out == 0) {
|
||||
mo->next = mballoc(DEFLATE_CHUNK_LEN, MB_HDLCOUT);
|
||||
olen += (mo->cnt = DEFLATE_CHUNK_LEN);
|
||||
mo = mo->next;
|
||||
mo->cnt = 0;
|
||||
OutputState.cx.next_out = MBUF_CTOP(mo);
|
||||
OutputState.cx.avail_out = DEFLATE_CHUNK_LEN;
|
||||
state->cx.next_out = MBUF_CTOP(mo);
|
||||
state->cx.avail_out = DEFLATE_CHUNK_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
olen += (mo->cnt = DEFLATE_CHUNK_LEN - OutputState.cx.avail_out);
|
||||
olen += (mo->cnt = DEFLATE_CHUNK_LEN - state->cx.avail_out);
|
||||
olen -= 4; /* exclude the trailing EMPTY_BLOCK */
|
||||
|
||||
/*
|
||||
|
@ -193,17 +194,20 @@ DeflateOutput(struct ccp *ccp, struct link *l, int pri, u_short proto,
|
|||
}
|
||||
|
||||
static void
|
||||
DeflateResetInput(void)
|
||||
DeflateResetInput(void *v)
|
||||
{
|
||||
InputState.seqno = 0;
|
||||
InputState.uncomp_rec = 0;
|
||||
inflateReset(&InputState.cx);
|
||||
struct deflate_state *state = (struct deflate_state *)v;
|
||||
|
||||
state->seqno = 0;
|
||||
state->uncomp_rec = 0;
|
||||
inflateReset(&state->cx);
|
||||
LogPrintf(LogCCP, "Deflate: Input channel reset\n");
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
DeflateInput(struct ccp *ccp, u_short *proto, struct mbuf *mi)
|
||||
DeflateInput(void *v, struct ccp *ccp, u_short *proto, struct mbuf *mi)
|
||||
{
|
||||
struct deflate_state *state = (struct deflate_state *)v;
|
||||
struct mbuf *mo, *mo_head, *mi_head;
|
||||
u_char *wp;
|
||||
int ilen, olen;
|
||||
|
@ -217,24 +221,24 @@ DeflateInput(struct ccp *ccp, u_short *proto, struct mbuf *mi)
|
|||
/* Check the sequence number. */
|
||||
seq = (hdr[0] << 8) + hdr[1];
|
||||
LogPrintf(LogDEBUG, "DeflateInput: Seq %d\n", seq);
|
||||
if (seq != InputState.seqno) {
|
||||
if (seq <= InputState.uncomp_rec)
|
||||
if (seq != state->seqno) {
|
||||
if (seq <= state->uncomp_rec)
|
||||
/*
|
||||
* So the peer's started at zero again - fine ! If we're wrong,
|
||||
* inflate() will fail. This is better than getting into a loop
|
||||
* trying to get a ResetReq to a busy sender.
|
||||
*/
|
||||
InputState.seqno = seq;
|
||||
state->seqno = seq;
|
||||
else {
|
||||
LogPrintf(LogERROR, "DeflateInput: Seq error: Got %d, expected %d\n",
|
||||
seq, InputState.seqno);
|
||||
seq, state->seqno);
|
||||
pfree(mi_head);
|
||||
CcpSendResetReq(&ccp->fsm);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
InputState.seqno++;
|
||||
InputState.uncomp_rec = 0;
|
||||
state->seqno++;
|
||||
state->uncomp_rec = 0;
|
||||
|
||||
/* Allocate an output mbuf */
|
||||
mo_head = mo = mballoc(DEFLATE_CHUNK_LEN, MB_IPIN);
|
||||
|
@ -248,10 +252,10 @@ DeflateInput(struct ccp *ccp, u_short *proto, struct mbuf *mi)
|
|||
* byte of the output and decide whether we have a compressed
|
||||
* proto field.
|
||||
*/
|
||||
InputState.cx.next_in = MBUF_CTOP(mi);
|
||||
InputState.cx.avail_in = mi->cnt;
|
||||
InputState.cx.next_out = wp + 1;
|
||||
InputState.cx.avail_out = 1;
|
||||
state->cx.next_in = MBUF_CTOP(mi);
|
||||
state->cx.avail_in = mi->cnt;
|
||||
state->cx.next_out = wp + 1;
|
||||
state->cx.avail_out = 1;
|
||||
ilen += mi->cnt;
|
||||
|
||||
flush = mi->next ? Z_NO_FLUSH : Z_SYNC_FLUSH;
|
||||
|
@ -259,45 +263,45 @@ DeflateInput(struct ccp *ccp, u_short *proto, struct mbuf *mi)
|
|||
olen = 0;
|
||||
|
||||
while (1) {
|
||||
if ((res = inflate(&InputState.cx, flush)) != Z_OK) {
|
||||
if ((res = inflate(&state->cx, flush)) != Z_OK) {
|
||||
if (res == Z_STREAM_END)
|
||||
break; /* Done */
|
||||
LogPrintf(LogERROR, "DeflateInput: inflate returned %d (%s)\n",
|
||||
res, InputState.cx.msg ? InputState.cx.msg : "");
|
||||
res, state->cx.msg ? state->cx.msg : "");
|
||||
pfree(mo_head);
|
||||
pfree(mi);
|
||||
CcpSendResetReq(&ccp->fsm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (flush == Z_SYNC_FLUSH && InputState.cx.avail_out != 0)
|
||||
if (flush == Z_SYNC_FLUSH && state->cx.avail_out != 0)
|
||||
break;
|
||||
|
||||
if (InputState.cx.avail_in == 0 && mi && (mi = mbfree(mi)) != NULL) {
|
||||
if (state->cx.avail_in == 0 && mi && (mi = mbfree(mi)) != NULL) {
|
||||
/* underflow */
|
||||
InputState.cx.next_in = MBUF_CTOP(mi);
|
||||
ilen += (InputState.cx.avail_in = mi->cnt);
|
||||
state->cx.next_in = MBUF_CTOP(mi);
|
||||
ilen += (state->cx.avail_in = mi->cnt);
|
||||
if (mi->next == NULL)
|
||||
flush = Z_SYNC_FLUSH;
|
||||
}
|
||||
|
||||
if (InputState.cx.avail_out == 0)
|
||||
if (state->cx.avail_out == 0)
|
||||
/* overflow */
|
||||
if (first) {
|
||||
if (!(wp[1] & 1)) {
|
||||
/* 2 byte proto, shuffle it back in output */
|
||||
wp[0] = wp[1];
|
||||
InputState.cx.next_out--;
|
||||
InputState.cx.avail_out = DEFLATE_CHUNK_LEN-1;
|
||||
state->cx.next_out--;
|
||||
state->cx.avail_out = DEFLATE_CHUNK_LEN-1;
|
||||
} else
|
||||
InputState.cx.avail_out = DEFLATE_CHUNK_LEN-2;
|
||||
state->cx.avail_out = DEFLATE_CHUNK_LEN-2;
|
||||
first = 0;
|
||||
} else {
|
||||
olen += (mo->cnt = DEFLATE_CHUNK_LEN);
|
||||
mo->next = mballoc(DEFLATE_CHUNK_LEN, MB_IPIN);
|
||||
mo = mo->next;
|
||||
InputState.cx.next_out = MBUF_CTOP(mo);
|
||||
InputState.cx.avail_out = DEFLATE_CHUNK_LEN;
|
||||
state->cx.next_out = MBUF_CTOP(mo);
|
||||
state->cx.avail_out = DEFLATE_CHUNK_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -311,7 +315,7 @@ DeflateInput(struct ccp *ccp, u_short *proto, struct mbuf *mi)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
olen += (mo->cnt = DEFLATE_CHUNK_LEN - InputState.cx.avail_out);
|
||||
olen += (mo->cnt = DEFLATE_CHUNK_LEN - state->cx.avail_out);
|
||||
|
||||
*proto = ((u_short)wp[0] << 8) | wp[1];
|
||||
mo_head->offset += 2;
|
||||
|
@ -328,24 +332,25 @@ DeflateInput(struct ccp *ccp, u_short *proto, struct mbuf *mi)
|
|||
* Simulate an EMPTY_BLOCK so that our dictionary stays in sync.
|
||||
* The peer will have silently removed this!
|
||||
*/
|
||||
InputState.cx.next_out = garbage;
|
||||
InputState.cx.avail_out = sizeof garbage;
|
||||
InputState.cx.next_in = EMPTY_BLOCK;
|
||||
InputState.cx.avail_in = sizeof EMPTY_BLOCK;
|
||||
inflate(&InputState.cx, Z_SYNC_FLUSH);
|
||||
state->cx.next_out = garbage;
|
||||
state->cx.avail_out = sizeof garbage;
|
||||
state->cx.next_in = EMPTY_BLOCK;
|
||||
state->cx.avail_in = sizeof EMPTY_BLOCK;
|
||||
inflate(&state->cx, Z_SYNC_FLUSH);
|
||||
|
||||
return mo_head;
|
||||
}
|
||||
|
||||
static void
|
||||
DeflateDictSetup(struct ccp *ccp, u_short proto, struct mbuf *mi)
|
||||
DeflateDictSetup(void *v, struct ccp *ccp, u_short proto, struct mbuf *mi)
|
||||
{
|
||||
struct deflate_state *state = (struct deflate_state *)v;
|
||||
int res, flush, expect_error;
|
||||
u_char *rp;
|
||||
struct mbuf *mi_head;
|
||||
short len;
|
||||
|
||||
LogPrintf(LogDEBUG, "DeflateDictSetup: Got seq %d\n", InputState.seqno);
|
||||
LogPrintf(LogDEBUG, "DeflateDictSetup: Got seq %d\n", state->seqno);
|
||||
|
||||
/*
|
||||
* Stuff an ``uncompressed data'' block header followed by the
|
||||
|
@ -372,41 +377,41 @@ DeflateDictSetup(struct ccp *ccp, u_short proto, struct mbuf *mi)
|
|||
rp[3] = (~len) & 0377; /* One's compliment of the length */
|
||||
rp[4] = (~len) >> 8;
|
||||
|
||||
InputState.cx.next_in = rp;
|
||||
InputState.cx.avail_in = mi->cnt;
|
||||
InputState.cx.next_out = garbage;
|
||||
InputState.cx.avail_out = sizeof garbage;
|
||||
state->cx.next_in = rp;
|
||||
state->cx.avail_in = mi->cnt;
|
||||
state->cx.next_out = garbage;
|
||||
state->cx.avail_out = sizeof garbage;
|
||||
flush = Z_NO_FLUSH;
|
||||
expect_error = 0;
|
||||
|
||||
while (1) {
|
||||
if ((res = inflate(&InputState.cx, flush)) != Z_OK) {
|
||||
if ((res = inflate(&state->cx, flush)) != Z_OK) {
|
||||
if (res == Z_STREAM_END)
|
||||
break; /* Done */
|
||||
if (expect_error && res == Z_BUF_ERROR)
|
||||
break;
|
||||
LogPrintf(LogERROR, "DeflateDictSetup: inflate returned %d (%s)\n",
|
||||
res, InputState.cx.msg ? InputState.cx.msg : "");
|
||||
res, state->cx.msg ? state->cx.msg : "");
|
||||
LogPrintf(LogERROR, "DeflateDictSetup: avail_in %d, avail_out %d\n",
|
||||
InputState.cx.avail_in, InputState.cx.avail_out);
|
||||
state->cx.avail_in, state->cx.avail_out);
|
||||
CcpSendResetReq(&ccp->fsm);
|
||||
mbfree(mi_head); /* lose our allocated ``head'' buf */
|
||||
return;
|
||||
}
|
||||
|
||||
if (flush == Z_SYNC_FLUSH && InputState.cx.avail_out != 0)
|
||||
if (flush == Z_SYNC_FLUSH && state->cx.avail_out != 0)
|
||||
break;
|
||||
|
||||
if (InputState.cx.avail_in == 0 && mi && (mi = mi->next) != NULL) {
|
||||
if (state->cx.avail_in == 0 && mi && (mi = mi->next) != NULL) {
|
||||
/* underflow */
|
||||
InputState.cx.next_in = MBUF_CTOP(mi);
|
||||
InputState.cx.avail_in = mi->cnt;
|
||||
state->cx.next_in = MBUF_CTOP(mi);
|
||||
state->cx.avail_in = mi->cnt;
|
||||
if (mi->next == NULL)
|
||||
flush = Z_SYNC_FLUSH;
|
||||
}
|
||||
|
||||
if (InputState.cx.avail_out == 0) {
|
||||
if (InputState.cx.avail_in == 0)
|
||||
if (state->cx.avail_out == 0) {
|
||||
if (state->cx.avail_in == 0)
|
||||
/*
|
||||
* This seems to be a bug in libz ! If inflate() finished
|
||||
* with 0 avail_in and 0 avail_out *and* this is the end of
|
||||
|
@ -420,16 +425,16 @@ DeflateDictSetup(struct ccp *ccp, u_short proto, struct mbuf *mi)
|
|||
*/
|
||||
expect_error = 1;
|
||||
/* overflow */
|
||||
InputState.cx.next_out = garbage;
|
||||
InputState.cx.avail_out = sizeof garbage;
|
||||
state->cx.next_out = garbage;
|
||||
state->cx.avail_out = sizeof garbage;
|
||||
}
|
||||
}
|
||||
|
||||
ccp->compin += len;
|
||||
ccp->uncompin += len;
|
||||
|
||||
InputState.seqno++;
|
||||
InputState.uncomp_rec++;
|
||||
state->seqno++;
|
||||
state->uncomp_rec++;
|
||||
mbfree(mi_head); /* lose our allocated ``head'' buf */
|
||||
}
|
||||
|
||||
|
@ -443,50 +448,21 @@ DeflateDispOpts(struct lcp_opt *o)
|
|||
}
|
||||
|
||||
static void
|
||||
DeflateGetInputOpts(struct lcp_opt *o)
|
||||
DeflateInitOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg)
|
||||
{
|
||||
o->id = TY_DEFLATE;
|
||||
o->len = 4;
|
||||
o->data[0] = ((iWindowSize-8)<<4)+8;
|
||||
o->data[1] = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
DeflateGetOutputOpts(struct lcp_opt *o)
|
||||
{
|
||||
o->id = TY_DEFLATE;
|
||||
o->len = 4;
|
||||
o->data[0] = ((oWindowSize-8)<<4)+8;
|
||||
o->data[1] = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
PppdDeflateGetInputOpts(struct lcp_opt *o)
|
||||
{
|
||||
o->id = TY_PPPD_DEFLATE;
|
||||
o->len = 4;
|
||||
o->data[0] = ((iWindowSize-8)<<4)+8;
|
||||
o->data[1] = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
PppdDeflateGetOutputOpts(struct lcp_opt *o)
|
||||
{
|
||||
o->id = TY_PPPD_DEFLATE;
|
||||
o->len = 4;
|
||||
o->data[0] = ((oWindowSize-8)<<4)+8;
|
||||
o->data[0] = ((cfg->deflate.out.winsize - 8) << 4) + 8;
|
||||
o->data[1] = '\0';
|
||||
}
|
||||
|
||||
static int
|
||||
DeflateSetOpts(struct lcp_opt *o, int *sz)
|
||||
DeflateSetOptsOutput(struct lcp_opt *o)
|
||||
{
|
||||
if (o->len != 4 || (o->data[0]&15) != 8 || o->data[1] != '\0') {
|
||||
if (o->len != 4 || (o->data[0] & 15) != 8 || o->data[1] != '\0')
|
||||
return MODE_REJ;
|
||||
}
|
||||
*sz = (o->data[0] >> 4) + 8;
|
||||
if (*sz > 15) {
|
||||
*sz = 15;
|
||||
|
||||
if ((o->data[0] >> 4) + 8 > 15) {
|
||||
o->data[0] = ((15 - 8) << 4) + 8;
|
||||
return MODE_NAK;
|
||||
}
|
||||
|
||||
|
@ -494,84 +470,89 @@ DeflateSetOpts(struct lcp_opt *o, int *sz)
|
|||
}
|
||||
|
||||
static int
|
||||
DeflateSetInputOpts(struct lcp_opt *o)
|
||||
DeflateSetOptsInput(struct lcp_opt *o, const struct ccp_config *cfg)
|
||||
{
|
||||
int res;
|
||||
res = DeflateSetOpts(o, &iWindowSize);
|
||||
if (res != MODE_ACK)
|
||||
DeflateGetInputOpts(o);
|
||||
return res;
|
||||
int want;
|
||||
|
||||
if (o->len != 4 || (o->data[0] & 15) != 8 || o->data[1] != '\0')
|
||||
return MODE_REJ;
|
||||
|
||||
want = (o->data[0] >> 4) + 8;
|
||||
if (cfg->deflate.in.winsize == 0) {
|
||||
if (want < 8 || want > 15) {
|
||||
o->data[0] = ((15 - 8) << 4) + 8;
|
||||
}
|
||||
} else if (want != cfg->deflate.in.winsize) {
|
||||
o->data[0] = ((cfg->deflate.in.winsize - 8) << 4) + 8;
|
||||
return MODE_NAK;
|
||||
}
|
||||
|
||||
return MODE_ACK;
|
||||
}
|
||||
|
||||
static int
|
||||
DeflateSetOutputOpts(struct lcp_opt *o)
|
||||
static void *
|
||||
DeflateInitInput(struct lcp_opt *o)
|
||||
{
|
||||
int res;
|
||||
res = DeflateSetOpts(o, &oWindowSize);
|
||||
if (res != MODE_ACK)
|
||||
DeflateGetOutputOpts(o);
|
||||
return res;
|
||||
struct deflate_state *state;
|
||||
|
||||
state = (struct deflate_state *)malloc(sizeof(struct deflate_state));
|
||||
if (state != NULL) {
|
||||
state->winsize = (o->data[0] >> 4) + 8;
|
||||
state->cx.zalloc = NULL;
|
||||
state->cx.opaque = NULL;
|
||||
state->cx.zfree = NULL;
|
||||
state->cx.next_out = NULL;
|
||||
if (inflateInit2(&state->cx, -state->winsize) == Z_OK)
|
||||
DeflateResetInput(state);
|
||||
else {
|
||||
free(state);
|
||||
state = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
static int
|
||||
PppdDeflateSetInputOpts(struct lcp_opt *o)
|
||||
static void *
|
||||
DeflateInitOutput(struct lcp_opt *o)
|
||||
{
|
||||
int res;
|
||||
res = DeflateSetOpts(o, &iWindowSize);
|
||||
if (res != MODE_ACK)
|
||||
PppdDeflateGetInputOpts(o);
|
||||
return res;
|
||||
}
|
||||
struct deflate_state *state;
|
||||
|
||||
static int
|
||||
PppdDeflateSetOutputOpts(struct lcp_opt *o)
|
||||
{
|
||||
int res;
|
||||
res = DeflateSetOpts(o, &oWindowSize);
|
||||
if (res != MODE_ACK)
|
||||
PppdDeflateGetOutputOpts(o);
|
||||
return res;
|
||||
}
|
||||
state = (struct deflate_state *)malloc(sizeof(struct deflate_state));
|
||||
if (state != NULL) {
|
||||
state->winsize = (o->data[0] >> 4) + 8;
|
||||
state->cx.zalloc = NULL;
|
||||
state->cx.opaque = NULL;
|
||||
state->cx.zfree = NULL;
|
||||
state->cx.next_in = NULL;
|
||||
if (deflateInit2(&state->cx, Z_DEFAULT_COMPRESSION, 8,
|
||||
-state->winsize, 8, Z_DEFAULT_STRATEGY) == Z_OK)
|
||||
DeflateResetOutput(state);
|
||||
else {
|
||||
free(state);
|
||||
state = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
DeflateInitInput(void)
|
||||
{
|
||||
InputState.cx.zalloc = NULL;
|
||||
InputState.cx.opaque = NULL;
|
||||
InputState.cx.zfree = NULL;
|
||||
InputState.cx.next_out = NULL;
|
||||
if (inflateInit2(&InputState.cx, -iWindowSize) != Z_OK)
|
||||
return 0;
|
||||
DeflateResetInput();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
DeflateInitOutput(void)
|
||||
{
|
||||
OutputState.cx.zalloc = NULL;
|
||||
OutputState.cx.opaque = NULL;
|
||||
OutputState.cx.zfree = NULL;
|
||||
OutputState.cx.next_in = NULL;
|
||||
if (deflateInit2(&OutputState.cx, Z_DEFAULT_COMPRESSION, 8,
|
||||
-oWindowSize, 8, Z_DEFAULT_STRATEGY) != Z_OK)
|
||||
return 0;
|
||||
DeflateResetOutput();
|
||||
return 1;
|
||||
return state;
|
||||
}
|
||||
|
||||
static void
|
||||
DeflateTermInput(void)
|
||||
DeflateTermInput(void *v)
|
||||
{
|
||||
iWindowSize = 15;
|
||||
inflateEnd(&InputState.cx);
|
||||
struct deflate_state *state = (struct deflate_state *)v;
|
||||
|
||||
inflateEnd(&state->cx);
|
||||
free(state);
|
||||
}
|
||||
|
||||
static void
|
||||
DeflateTermOutput(void)
|
||||
DeflateTermOutput(void *v)
|
||||
{
|
||||
oWindowSize = 15;
|
||||
deflateEnd(&OutputState.cx);
|
||||
struct deflate_state *state = (struct deflate_state *)v;
|
||||
|
||||
deflateEnd(&state->cx);
|
||||
free(state);
|
||||
}
|
||||
|
||||
const struct ccp_algorithm PppdDeflateAlgorithm = {
|
||||
|
@ -579,8 +560,7 @@ const struct ccp_algorithm PppdDeflateAlgorithm = {
|
|||
ConfPppdDeflate,
|
||||
DeflateDispOpts,
|
||||
{
|
||||
PppdDeflateGetInputOpts,
|
||||
PppdDeflateSetInputOpts,
|
||||
DeflateSetOptsInput,
|
||||
DeflateInitInput,
|
||||
DeflateTermInput,
|
||||
DeflateResetInput,
|
||||
|
@ -588,8 +568,8 @@ const struct ccp_algorithm PppdDeflateAlgorithm = {
|
|||
DeflateDictSetup
|
||||
},
|
||||
{
|
||||
PppdDeflateGetOutputOpts,
|
||||
PppdDeflateSetOutputOpts,
|
||||
DeflateInitOptsOutput,
|
||||
DeflateSetOptsOutput,
|
||||
DeflateInitOutput,
|
||||
DeflateTermOutput,
|
||||
DeflateResetOutput,
|
||||
|
@ -602,8 +582,7 @@ const struct ccp_algorithm DeflateAlgorithm = {
|
|||
ConfDeflate,
|
||||
DeflateDispOpts,
|
||||
{
|
||||
DeflateGetInputOpts,
|
||||
DeflateSetInputOpts,
|
||||
DeflateSetOptsInput,
|
||||
DeflateInitInput,
|
||||
DeflateTermInput,
|
||||
DeflateResetInput,
|
||||
|
@ -611,8 +590,8 @@ const struct ccp_algorithm DeflateAlgorithm = {
|
|||
DeflateDictSetup
|
||||
},
|
||||
{
|
||||
DeflateGetOutputOpts,
|
||||
DeflateSetOutputOpts,
|
||||
DeflateInitOptsOutput,
|
||||
DeflateSetOptsOutput,
|
||||
DeflateInitOutput,
|
||||
DeflateTermOutput,
|
||||
DeflateResetOutput,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $Id: ppp.8,v 1.97.2.4 1998/03/16 07:37:56 brian Exp $
|
||||
.\" $Id: ppp.8,v 1.97.2.5 1998/03/16 22:52:42 brian Exp $
|
||||
.Dd 20 September 1995
|
||||
.Os FreeBSD
|
||||
.Dt PPP 8
|
||||
|
@ -1997,6 +1997,20 @@ for security reasons.
|
|||
This sets the authentication id used in client mode PAP or CHAP negotiation.
|
||||
.It set ctsrts
|
||||
This sets hardware flow control and is the default.
|
||||
.It set deflate out-winsize [in-winsize]
|
||||
This sets the DEFLATE algorithms default outgoing and incoming window
|
||||
sizes. Both
|
||||
.Ar out-winsize
|
||||
and
|
||||
.Ar in-winsize
|
||||
must be values between
|
||||
.Em 8
|
||||
and
|
||||
.Em 15 .
|
||||
If
|
||||
.Ar in-winsize
|
||||
is specified, ppp will insist that this window size is used and will not
|
||||
accept any other values from the peer.
|
||||
.It set device|line value[,value...]
|
||||
This sets the device(s) to which
|
||||
.Nm
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: pred.c,v 1.20.2.4 1998/02/23 00:38:41 brian Exp $
|
||||
* $Id: pred.c,v 1.20.2.5 1998/03/13 00:44:22 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -59,16 +59,16 @@
|
|||
* A better hash function would result in additional compression,
|
||||
* at the expense of time.
|
||||
*/
|
||||
#define IHASH(x) do {iHash = (iHash << 4) ^ (x);} while(0)
|
||||
#define OHASH(x) do {oHash = (oHash << 4) ^ (x);} while(0)
|
||||
#define HASH(state, x) state->hash = (state->hash << 4) ^ (x)
|
||||
#define GUESS_TABLE_SIZE 65536
|
||||
|
||||
static unsigned short int iHash, oHash;
|
||||
static unsigned char *InputGuessTable;
|
||||
static unsigned char *OutputGuessTable;
|
||||
struct pred1_state {
|
||||
u_short hash;
|
||||
u_char dict[GUESS_TABLE_SIZE];
|
||||
};
|
||||
|
||||
static int
|
||||
compress(u_char * source, u_char * dest, int len)
|
||||
compress(struct pred1_state *state, u_char *source, u_char *dest, int len)
|
||||
{
|
||||
int i, bitmask;
|
||||
unsigned char *flagdest, flags, *orgdest;
|
||||
|
@ -78,13 +78,13 @@ compress(u_char * source, u_char * dest, int len)
|
|||
flagdest = dest++;
|
||||
flags = 0; /* All guess wrong initially */
|
||||
for (bitmask = 1, i = 0; i < 8 && len; i++, bitmask <<= 1) {
|
||||
if (OutputGuessTable[oHash] == *source) {
|
||||
if (state->dict[state->hash] == *source) {
|
||||
flags |= bitmask; /* Guess was right - don't output */
|
||||
} else {
|
||||
OutputGuessTable[oHash] = *source;
|
||||
state->dict[state->hash] = *source;
|
||||
*dest++ = *source; /* Guess wrong, output char */
|
||||
}
|
||||
OHASH(*source++);
|
||||
HASH(state, *source++);
|
||||
len--;
|
||||
}
|
||||
*flagdest = flags;
|
||||
|
@ -93,19 +93,17 @@ compress(u_char * source, u_char * dest, int len)
|
|||
}
|
||||
|
||||
static void
|
||||
SyncTable(u_char * source, u_char * dest, int len)
|
||||
SyncTable(struct pred1_state *state, u_char * source, u_char * dest, int len)
|
||||
{
|
||||
|
||||
while (len--) {
|
||||
if (InputGuessTable[iHash] != *source) {
|
||||
InputGuessTable[iHash] = *source;
|
||||
}
|
||||
IHASH(*dest++ = *source++);
|
||||
if (state->dict[state->hash] != *source)
|
||||
state->dict[state->hash] = *source;
|
||||
HASH(state, *dest++ = *source++);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
decompress(u_char * source, u_char * dest, int len)
|
||||
decompress(struct pred1_state *state, u_char * source, u_char * dest, int len)
|
||||
{
|
||||
int i, bitmask;
|
||||
unsigned char flags, *orgdest;
|
||||
|
@ -116,78 +114,70 @@ decompress(u_char * source, u_char * dest, int len)
|
|||
len--;
|
||||
for (i = 0, bitmask = 1; i < 8; i++, bitmask <<= 1) {
|
||||
if (flags & bitmask) {
|
||||
*dest = InputGuessTable[iHash]; /* Guess correct */
|
||||
*dest = state->dict[state->hash]; /* Guess correct */
|
||||
} else {
|
||||
if (!len)
|
||||
break; /* we seem to be really done -- cabo */
|
||||
InputGuessTable[iHash] = *source; /* Guess wrong */
|
||||
state->dict[state->hash] = *source; /* Guess wrong */
|
||||
*dest = *source++; /* Read from source */
|
||||
len--;
|
||||
}
|
||||
IHASH(*dest++);
|
||||
HASH(state, *dest++);
|
||||
}
|
||||
}
|
||||
return (dest - orgdest);
|
||||
}
|
||||
|
||||
static void
|
||||
Pred1TermInput(void)
|
||||
Pred1Term(void *v)
|
||||
{
|
||||
if (InputGuessTable != NULL) {
|
||||
free(InputGuessTable);
|
||||
InputGuessTable = NULL;
|
||||
}
|
||||
struct pred1_state *state = (struct pred1_state *)v;
|
||||
free(state);
|
||||
}
|
||||
|
||||
static void
|
||||
Pred1TermOutput(void)
|
||||
Pred1ResetInput(void *v)
|
||||
{
|
||||
if (OutputGuessTable != NULL) {
|
||||
free(OutputGuessTable);
|
||||
OutputGuessTable = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
Pred1ResetInput(void)
|
||||
{
|
||||
iHash = 0;
|
||||
memset(InputGuessTable, '\0', GUESS_TABLE_SIZE);
|
||||
struct pred1_state *state = (struct pred1_state *)v;
|
||||
state->hash = 0;
|
||||
memset(state->dict, '\0', sizeof state->dict);
|
||||
LogPrintf(LogCCP, "Predictor1: Input channel reset\n");
|
||||
}
|
||||
|
||||
static void
|
||||
Pred1ResetOutput(void)
|
||||
Pred1ResetOutput(void *v)
|
||||
{
|
||||
oHash = 0;
|
||||
memset(OutputGuessTable, '\0', GUESS_TABLE_SIZE);
|
||||
struct pred1_state *state = (struct pred1_state *)v;
|
||||
state->hash = 0;
|
||||
memset(state->dict, '\0', sizeof state->dict);
|
||||
LogPrintf(LogCCP, "Predictor1: Output channel reset\n");
|
||||
}
|
||||
|
||||
static int
|
||||
Pred1InitInput(void)
|
||||
static void *
|
||||
Pred1InitInput(struct lcp_opt *o)
|
||||
{
|
||||
if (InputGuessTable == NULL)
|
||||
if ((InputGuessTable = malloc(GUESS_TABLE_SIZE)) == NULL)
|
||||
return 0;
|
||||
Pred1ResetInput();
|
||||
return 1;
|
||||
struct pred1_state *state;
|
||||
state = (struct pred1_state *)malloc(sizeof(struct pred1_state));
|
||||
if (state != NULL)
|
||||
Pred1ResetInput(state);
|
||||
return state;
|
||||
}
|
||||
|
||||
static void *
|
||||
Pred1InitOutput(struct lcp_opt *o)
|
||||
{
|
||||
struct pred1_state *state;
|
||||
state = (struct pred1_state *)malloc(sizeof(struct pred1_state));
|
||||
if (state != NULL)
|
||||
Pred1ResetOutput(state);
|
||||
return state;
|
||||
}
|
||||
|
||||
static int
|
||||
Pred1InitOutput(void)
|
||||
{
|
||||
if (OutputGuessTable == NULL)
|
||||
if ((OutputGuessTable = malloc(GUESS_TABLE_SIZE)) == NULL)
|
||||
return 0;
|
||||
Pred1ResetOutput();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
Pred1Output(struct ccp *ccp, struct link *l, int pri, u_short proto,
|
||||
Pred1Output(void *v, struct ccp *ccp, struct link *l, int pri, u_short proto,
|
||||
struct mbuf *bp)
|
||||
{
|
||||
struct pred1_state *state = (struct pred1_state *)v;
|
||||
struct mbuf *mwp;
|
||||
u_char *cp, *wp, *hp;
|
||||
int orglen, len;
|
||||
|
@ -206,7 +196,7 @@ Pred1Output(struct ccp *ccp, struct link *l, int pri, u_short proto,
|
|||
fcs = HdlcFcs(INITFCS, bufp, 2 + orglen);
|
||||
fcs = ~fcs;
|
||||
|
||||
len = compress(bufp + 2, wp, orglen);
|
||||
len = compress(state, bufp + 2, wp, orglen);
|
||||
LogPrintf(LogDEBUG, "Pred1Output: orglen (%d) --> len (%d)\n", orglen, len);
|
||||
ccp->uncompout += orglen;
|
||||
if (len < orglen) {
|
||||
|
@ -227,8 +217,9 @@ Pred1Output(struct ccp *ccp, struct link *l, int pri, u_short proto,
|
|||
}
|
||||
|
||||
static struct mbuf *
|
||||
Pred1Input(struct ccp *ccp, u_short *proto, struct mbuf *bp)
|
||||
Pred1Input(void *v, struct ccp *ccp, u_short *proto, struct mbuf *bp)
|
||||
{
|
||||
struct pred1_state *state = (struct pred1_state *)v;
|
||||
u_char *cp, *pp;
|
||||
int len, olen, len1;
|
||||
struct mbuf *wp;
|
||||
|
@ -245,7 +236,7 @@ Pred1Input(struct ccp *ccp, u_short *proto, struct mbuf *bp)
|
|||
len += *cp++;
|
||||
ccp->uncompin += len & 0x7fff;
|
||||
if (len & 0x8000) {
|
||||
len1 = decompress(cp, pp, olen - 4);
|
||||
len1 = decompress(state, cp, pp, olen - 4);
|
||||
ccp->compin += olen;
|
||||
len &= 0x7fff;
|
||||
if (len != len1) { /* Error is detected. Send reset request */
|
||||
|
@ -259,7 +250,7 @@ Pred1Input(struct ccp *ccp, u_short *proto, struct mbuf *bp)
|
|||
pp += len1;
|
||||
} else {
|
||||
ccp->compin += len;
|
||||
SyncTable(cp, pp, len);
|
||||
SyncTable(state, cp, pp, len);
|
||||
cp += len;
|
||||
pp += len;
|
||||
}
|
||||
|
@ -295,7 +286,7 @@ Pred1Input(struct ccp *ccp, u_short *proto, struct mbuf *bp)
|
|||
}
|
||||
|
||||
static void
|
||||
Pred1DictSetup(struct ccp *ccp, u_short proto, struct mbuf * bp)
|
||||
Pred1DictSetup(void *v, struct ccp *ccp, u_short proto, struct mbuf * bp)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -306,40 +297,44 @@ Pred1DispOpts(struct lcp_opt *o)
|
|||
}
|
||||
|
||||
static void
|
||||
Pred1GetOpts(struct lcp_opt *o)
|
||||
Pred1InitOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg)
|
||||
{
|
||||
o->id = TY_PRED1;
|
||||
o->len = 2;
|
||||
}
|
||||
|
||||
static int
|
||||
Pred1SetOpts(struct lcp_opt *o)
|
||||
Pred1SetOptsOutput(struct lcp_opt *o)
|
||||
{
|
||||
if (o->id != TY_PRED1 || o->len != 2) {
|
||||
Pred1GetOpts(o);
|
||||
if (o->len != 2) {
|
||||
o->len = 2;
|
||||
return MODE_NAK;
|
||||
}
|
||||
return MODE_ACK;
|
||||
}
|
||||
|
||||
static int
|
||||
Pred1SetOptsInput(struct lcp_opt *o, const struct ccp_config *cfg)
|
||||
{
|
||||
return Pred1SetOptsOutput(o);
|
||||
}
|
||||
|
||||
const struct ccp_algorithm Pred1Algorithm = {
|
||||
TY_PRED1,
|
||||
ConfPred1,
|
||||
Pred1DispOpts,
|
||||
{
|
||||
Pred1GetOpts,
|
||||
Pred1SetOpts,
|
||||
Pred1SetOptsInput,
|
||||
Pred1InitInput,
|
||||
Pred1TermInput,
|
||||
Pred1Term,
|
||||
Pred1ResetInput,
|
||||
Pred1Input,
|
||||
Pred1DictSetup
|
||||
},
|
||||
{
|
||||
Pred1GetOpts,
|
||||
Pred1SetOpts,
|
||||
Pred1InitOptsOutput,
|
||||
Pred1SetOptsOutput,
|
||||
Pred1InitOutput,
|
||||
Pred1TermOutput,
|
||||
Pred1Term,
|
||||
Pred1ResetOutput,
|
||||
Pred1Output
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue