Make all CCP negotiation data dynamic and add a

``set deflate'' command to configure the DEFLATE
default window size.
This commit is contained in:
Brian Somers 1998-03-17 22:29:12 +00:00
parent fd33683210
commit 03036ec70d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/MP/; revision=34648
7 changed files with 441 additions and 346 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.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;
}

View File

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

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.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},

View File

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

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.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,

View File

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

View File

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