summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ppp/ccp.c
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>1998-05-21 21:49:08 +0000
committerbrian <brian@FreeBSD.org>1998-05-21 21:49:08 +0000
commit56df88b778aee0e60678672b107a48a8ea05cb48 (patch)
tree13b88ca17b38e787c84b0cd242677b3c3c0b93c3 /usr.sbin/ppp/ccp.c
parente077fa331b8a428923ded3a95d0b8d47084cf670 (diff)
downloadFreeBSD-src-56df88b778aee0e60678672b107a48a8ea05cb48.zip
FreeBSD-src-56df88b778aee0e60678672b107a48a8ea05cb48.tar.gz
MFMP: Make ppp multilink capable.
See the file README.changes, and re-read the man page.
Diffstat (limited to 'usr.sbin/ppp/ccp.c')
-rw-r--r--usr.sbin/ppp/ccp.c556
1 files changed, 357 insertions, 199 deletions
diff --git a/usr.sbin/ppp/ccp.c b/usr.sbin/ppp/ccp.c
index 9b5de4b..12ace1a 100644
--- a/usr.sbin/ppp/ccp.c
+++ b/usr.sbin/ppp/ccp.c
@@ -17,16 +17,20 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: ccp.c,v 1.30 1998/01/21 02:15:10 brian Exp $
+ * $Id: ccp.c,v 1.30.2.45 1998/05/21 01:26:05 brian Exp $
*
* TODO:
* o Support other compression protocols
*/
-#include <sys/param.h>
+#include <sys/types.h>
#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <sys/un.h>
#include <stdio.h>
-#include <string.h>
+#include <stdlib.h>
+#include <termios.h>
#include "command.h"
#include "mbuf.h"
@@ -37,47 +41,53 @@
#include "lcpproto.h"
#include "lcp.h"
#include "ccp.h"
-#include "phase.h"
-#include "loadalias.h"
-#include "vars.h"
#include "pred.h"
#include "deflate.h"
-
-struct ccpstate CcpInfo = { -1, -1, -1, -1 };
+#include "throughput.h"
+#include "iplist.h"
+#include "slcompress.h"
+#include "ipcp.h"
+#include "filter.h"
+#include "descriptor.h"
+#include "prompt.h"
+#include "lqr.h"
+#include "hdlc.h"
+#include "link.h"
+#include "mp.h"
+#include "async.h"
+#include "physical.h"
+#include "bundle.h"
static void CcpSendConfigReq(struct fsm *);
-static void CcpSendTerminateReq(struct fsm *);
-static void CcpSendTerminateAck(struct fsm *);
-static void CcpDecodeConfig(u_char *, int, int);
+static void CcpSentTerminateReq(struct fsm *);
+static void CcpSendTerminateAck(struct fsm *, u_char);
+static void CcpDecodeConfig(struct fsm *, u_char *, int, int,
+ struct fsm_decode *);
static void CcpLayerStart(struct fsm *);
static void CcpLayerFinish(struct fsm *);
-static void CcpLayerUp(struct fsm *);
+static int CcpLayerUp(struct fsm *);
static void CcpLayerDown(struct fsm *);
static void CcpInitRestartCounter(struct fsm *);
+static void CcpRecvResetReq(struct fsm *);
+static void CcpRecvResetAck(struct fsm *, u_char);
-struct fsm CcpFsm = {
- "CCP",
- PROTO_CCP,
- CCP_MAXCODE,
- 0,
- ST_INITIAL,
- 0, 0, 0,
- {0, 0, 0, NULL, NULL, NULL}, /* FSM timer */
- {0, 0, 0, NULL, NULL, NULL}, /* Open timer */
- {0, 0, 0, NULL, NULL, NULL}, /* Stopped timer */
- LogCCP,
-
+static struct fsm_callbacks ccp_Callbacks = {
CcpLayerUp,
CcpLayerDown,
CcpLayerStart,
CcpLayerFinish,
CcpInitRestartCounter,
CcpSendConfigReq,
- CcpSendTerminateReq,
+ CcpSentTerminateReq,
CcpSendTerminateAck,
CcpDecodeConfig,
+ CcpRecvResetReq,
+ CcpRecvResetAck
};
+static const char *ccp_TimerNames[] =
+ {"CCP restart", "CCP openmode", "CCP stopped"};
+
static char const *cftypes[] = {
/* Check out the latest ``Compression Control Protocol'' rfc (rfc1962.txt) */
"OUI", /* 0: OUI */
@@ -88,14 +98,14 @@ static char const *cftypes[] = {
"???", "???", "???", "???", "???", "???",
"HWPPC", /* 16: Hewlett-Packard PPC */
"STAC", /* 17: Stac Electronics LZS (rfc1974) */
- "MSPPC", /* 18: Microsoft PPC */
+ "MPPC", /* 18: Microsoft PPC (rfc2118) */
"GAND", /* 19: Gandalf FZA (rfc1993) */
"V42BIS", /* 20: ARG->DATA.42bis compression */
"BSD", /* 21: BSD LZW Compress */
"???",
"LZS-DCP", /* 23: LZS-DCP Compression Protocol (rfc1967) */
"MAGNALINK/DEFLATE", /* 24: Magnalink Variable Resource (rfc1975) */
- /* 24: Deflate (according to pppd-2.3.1) */
+ /* 24: Deflate (according to pppd-2.3.*) */
"DCE", /* 25: Data Circuit-Terminating Equip (rfc1976) */
"DEFLATE", /* 26: Deflate (rfc1979) */
};
@@ -117,316 +127,464 @@ static const struct ccp_algorithm *algorithm[] = {
&PppdDeflateAlgorithm
};
-static int in_algorithm = -1;
-static int out_algorithm = -1;
#define NALGORITHMS (sizeof algorithm/sizeof algorithm[0])
int
-ReportCcpStatus(struct cmdargs const *arg)
+ccp_ReportStatus(struct cmdargs const *arg)
{
- if (VarTerm) {
- fprintf(VarTerm, "%s [%s]\n", CcpFsm.name, StateNames[CcpFsm.state]);
- fprintf(VarTerm, "My protocol = %s, His protocol = %s\n",
- protoname(CcpInfo.my_proto), protoname(CcpInfo.his_proto));
- fprintf(VarTerm, "Output: %ld --> %ld, Input: %ld --> %ld\n",
- CcpInfo.uncompout, CcpInfo.compout,
- CcpInfo.compin, CcpInfo.uncompin);
- }
+ struct link *l;
+ struct ccp *ccp;
+
+ if (!(l = command_ChooseLink(arg)))
+ return -1;
+ ccp = &l->ccp;
+
+ prompt_Printf(arg->prompt, "%s: %s [%s]\n", l->name, ccp->fsm.name,
+ State2Nam(ccp->fsm.state));
+ prompt_Printf(arg->prompt, " My protocol = %s, His protocol = %s\n",
+ protoname(ccp->my_proto), protoname(ccp->his_proto));
+ prompt_Printf(arg->prompt, " Output: %ld --> %ld, Input: %ld --> %ld\n",
+ ccp->uncompout, ccp->compout,
+ ccp->compin, ccp->uncompin);
+
+ prompt_Printf(arg->prompt, "\n Defaults: ");
+ prompt_Printf(arg->prompt, "FSM retry = %us\n", ccp->cfg.fsmretry);
+ prompt_Printf(arg->prompt, " deflate windows: ");
+ prompt_Printf(arg->prompt, "incoming = %d, ", ccp->cfg.deflate.in.winsize);
+ prompt_Printf(arg->prompt, "outgoing = %d\n", ccp->cfg.deflate.out.winsize);
+ prompt_Printf(arg->prompt, " DEFLATE: %s\n",
+ command_ShowNegval(ccp->cfg.neg[CCP_NEG_DEFLATE]));
+ prompt_Printf(arg->prompt, " PREDICTOR1: %s\n",
+ command_ShowNegval(ccp->cfg.neg[CCP_NEG_PRED1]));
+ prompt_Printf(arg->prompt, " DEFLATE24: %s\n",
+ command_ShowNegval(ccp->cfg.neg[CCP_NEG_DEFLATE24]));
return 0;
}
-static void
-ccpstateInit(void)
+void
+ccp_SetupCallbacks(struct ccp *ccp)
+{
+ ccp->fsm.fn = &ccp_Callbacks;
+ ccp->fsm.FsmTimer.name = ccp_TimerNames[0];
+ ccp->fsm.OpenTimer.name = ccp_TimerNames[1];
+ ccp->fsm.StoppedTimer.name = ccp_TimerNames[2];
+}
+
+void
+ccp_Init(struct ccp *ccp, struct bundle *bundle, struct link *l,
+ const struct fsm_parent *parent)
{
- if (CcpInfo.in_init)
- (*algorithm[in_algorithm]->i.Term)();
- if (CcpInfo.out_init)
- (*algorithm[out_algorithm]->o.Term)();
- in_algorithm = -1;
- out_algorithm = -1;
- memset(&CcpInfo, '\0', sizeof CcpInfo);
- CcpInfo.his_proto = CcpInfo.my_proto = -1;
- CcpInfo.reset_sent = CcpInfo.last_reset = -1;
+ /* Initialise ourselves */
+
+ fsm_Init(&ccp->fsm, "CCP", PROTO_CCP, 1, CCP_MAXCODE, 10, LogCCP,
+ bundle, l, parent, &ccp_Callbacks, ccp_TimerNames);
+
+ ccp->cfg.deflate.in.winsize = 0;
+ ccp->cfg.deflate.out.winsize = 15;
+ ccp->cfg.fsmretry = DEF_FSMRETRY;
+ ccp->cfg.neg[CCP_NEG_DEFLATE] = NEG_ENABLED|NEG_ACCEPTED;
+ ccp->cfg.neg[CCP_NEG_PRED1] = NEG_ENABLED|NEG_ACCEPTED;
+ ccp->cfg.neg[CCP_NEG_DEFLATE24] = 0;
+
+ ccp_Setup(ccp);
}
void
-CcpInit()
+ccp_Setup(struct ccp *ccp)
{
- FsmInit(&CcpFsm);
- ccpstateInit();
- CcpFsm.maxconfig = 10;
+ /* Set ourselves up for a startup */
+ ccp->fsm.open_mode = 0;
+ 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.state = ccp->out.state = NULL;
+ ccp->in.opt.id = -1;
+ ccp->out.opt = NULL;
+ ccp->his_reject = ccp->my_reject = 0;
+ ccp->uncompout = ccp->compout = 0;
+ ccp->uncompin = ccp->compin = 0;
}
static void
CcpInitRestartCounter(struct fsm *fp)
{
- fp->FsmTimer.load = VarRetryTimeout * SECTICKS;
+ /* Set fsm timer load */
+ struct ccp *ccp = fsm2ccp(fp);
+
+ fp->FsmTimer.load = ccp->cfg.fsmretry * SECTICKS;
fp->restart = 5;
}
static void
CcpSendConfigReq(struct fsm *fp)
{
- u_char *cp;
- int f;
-
- LogPrintf(LogCCP, "CcpSendConfigReq\n");
- cp = ReqBuff;
- CcpInfo.my_proto = -1;
- out_algorithm = -1;
+ /* Send config REQ please */
+ struct ccp *ccp = fsm2ccp(fp);
+ struct ccp_opt **o;
+ u_char *cp, buff[100];
+ int f, alloc;
+
+ cp = buff;
+ o = &ccp->out.opt;
+ alloc = ccp->his_reject == 0 && ccp->out.opt == NULL;
+ ccp->my_proto = -1;
+ ccp->out.algorithm = -1;
for (f = 0; f < NALGORITHMS; f++)
- if (Enabled(algorithm[f]->Conf) && !REJECTED(&CcpInfo, algorithm[f]->id)) {
- struct lcp_opt o;
-
- (*algorithm[f]->o.Get)(&o);
- cp += LcpPutConf(LogCCP, cp, &o, cftypes[o.id],
- (*algorithm[f]->Disp)(&o));
- CcpInfo.my_proto = o.id;
- out_algorithm = f;
+ if (IsEnabled(ccp->cfg.neg[algorithm[f]->Neg]) &&
+ !REJECTED(ccp, algorithm[f]->id)) {
+
+ if (!alloc)
+ for (o = &ccp->out.opt; *o != NULL; o = &(*o)->next)
+ if ((*o)->val.id == algorithm[f]->id && (*o)->algorithm == f)
+ break;
+
+ if (alloc || *o == NULL) {
+ *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);
+ }
+
+ if (cp + (*o)->val.len > buff + sizeof buff) {
+ log_Printf(LogERROR, "%s: CCP REQ buffer overrun !\n", fp->link->name);
+ break;
+ }
+ memcpy(cp, &(*o)->val, (*o)->val.len);
+ cp += (*o)->val.len;
+
+ ccp->my_proto = (*o)->val.id;
+ ccp->out.algorithm = f;
+
+ if (alloc)
+ o = &(*o)->next;
}
- FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff);
+
+ fsm_Output(fp, CODE_CONFIGREQ, fp->reqid, buff, cp - buff);
}
void
-CcpSendResetReq(struct fsm *fp)
+ccp_SendResetReq(struct fsm *fp)
{
- LogPrintf(LogCCP, "SendResetReq(%d)\n", fp->reqid);
- CcpInfo.reset_sent = fp->reqid;
- CcpInfo.last_reset = -1;
- FsmOutput(fp, CODE_RESETREQ, fp->reqid, NULL, 0);
+ /* We can't read our input - ask peer to reset */
+ struct ccp *ccp = fsm2ccp(fp);
+
+ ccp->reset_sent = fp->reqid;
+ ccp->last_reset = -1;
+ fsm_Output(fp, CODE_RESETREQ, fp->reqid, NULL, 0);
}
static void
-CcpSendTerminateReq(struct fsm *fp)
+CcpSentTerminateReq(struct fsm *fp)
{
- /* XXX: No code yet */
+ /* Term REQ just sent by FSM */
}
static void
-CcpSendTerminateAck(struct fsm *fp)
+CcpSendTerminateAck(struct fsm *fp, u_char id)
{
- LogPrintf(LogCCP, "CcpSendTerminateAck\n");
- FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0);
+ /* Send Term ACK please */
+ fsm_Output(fp, CODE_TERMACK, id, NULL, 0);
}
-void
+static void
CcpRecvResetReq(struct fsm *fp)
{
- if (out_algorithm >= 0 && out_algorithm < NALGORITHMS)
- (*algorithm[out_algorithm]->o.Reset)();
+ /* Got a reset REQ, reset outgoing dictionary */
+ struct ccp *ccp = fsm2ccp(fp);
+ if (ccp->out.state != NULL)
+ (*algorithm[ccp->out.algorithm]->o.Reset)(ccp->out.state);
}
static void
CcpLayerStart(struct fsm *fp)
{
- LogPrintf(LogCCP, "CcpLayerStart.\n");
+ /* We're about to start up ! */
+ log_Printf(LogCCP, "%s: CcpLayerStart.\n", fp->link->name);
}
static void
CcpLayerFinish(struct fsm *fp)
{
- LogPrintf(LogCCP, "CcpLayerFinish.\n");
- ccpstateInit();
+ /* We're now down */
+ struct ccp *ccp = fsm2ccp(fp);
+ struct ccp_opt *next;
+
+ log_Printf(LogCCP, "%s: CcpLayerFinish.\n", fp->link->name);
+ if (ccp->in.state != NULL) {
+ (*algorithm[ccp->in.algorithm]->i.Term)(ccp->in.state);
+ ccp->in.state = NULL;
+ ccp->in.algorithm = -1;
+ }
+ if (ccp->out.state != NULL) {
+ (*algorithm[ccp->out.algorithm]->o.Term)(ccp->out.state);
+ ccp->out.state = NULL;
+ ccp->out.algorithm = -1;
+ }
+ ccp->his_reject = ccp->my_reject = 0;
+
+ while (ccp->out.opt) {
+ next = ccp->out.opt->next;
+ free(ccp->out.opt);
+ ccp->out.opt = next;
+ }
}
static void
CcpLayerDown(struct fsm *fp)
{
- LogPrintf(LogCCP, "CcpLayerDown.\n");
- ccpstateInit();
+ /* About to come down */
+ log_Printf(LogCCP, "%s: CcpLayerDown.\n", fp->link->name);
}
/*
* Called when CCP has reached the OPEN state
*/
-static void
+static int
CcpLayerUp(struct fsm *fp)
{
- LogPrintf(LogCCP, "CcpLayerUp(%d).\n", fp->state);
- LogPrintf(LogCCP, "Out = %s[%d], In = %s[%d]\n",
- protoname(CcpInfo.my_proto), CcpInfo.my_proto,
- protoname(CcpInfo.his_proto), CcpInfo.his_proto);
- if (!CcpInfo.in_init && in_algorithm >= 0 && in_algorithm < NALGORITHMS) {
- (*algorithm[in_algorithm]->i.Init)();
- CcpInfo.in_init = 1;
- }
- if (!CcpInfo.out_init && out_algorithm >= 0 && out_algorithm < NALGORITHMS) {
- (*algorithm[out_algorithm]->o.Init)();
- CcpInfo.out_init = 1;
+ /* We're now up */
+ struct ccp *ccp = fsm2ccp(fp);
+ log_Printf(LogCCP, "%s: CcpLayerUp.\n", fp->link->name);
+ 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) {
+ log_Printf(LogERROR, "%s: %s (in) initialisation failure\n",
+ fp->link->name, protoname(ccp->his_proto));
+ ccp->his_proto = ccp->my_proto = -1;
+ fsm_Close(fp);
+ }
}
-}
-void
-CcpUp()
-{
- FsmUp(&CcpFsm);
- LogPrintf(LogCCP, "CCP Up event!!\n");
-}
-
-void
-CcpOpen()
-{
- int f;
-
- for (f = 0; f < NALGORITHMS; f++)
- if (Enabled(algorithm[f]->Conf)) {
- CcpFsm.open_mode = 0;
- FsmOpen(&CcpFsm);
- break;
+ 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) {
+ log_Printf(LogERROR, "%s: %s (out) initialisation failure\n",
+ fp->link->name, protoname(ccp->my_proto));
+ ccp->his_proto = ccp->my_proto = -1;
+ fsm_Close(fp);
}
+ }
- if (f == NALGORITHMS)
- for (f = 0; f < NALGORITHMS; f++)
- if (Acceptable(algorithm[f]->Conf)) {
- CcpFsm.open_mode = OPEN_PASSIVE;
- FsmOpen(&CcpFsm);
- break;
- }
+ log_Printf(LogCCP, "%s: Out = %s[%d], In = %s[%d]\n",
+ fp->link->name, protoname(ccp->my_proto), ccp->my_proto,
+ protoname(ccp->his_proto), ccp->his_proto);
+ return 1;
}
static void
-CcpDecodeConfig(u_char *cp, int plen, int mode_type)
+CcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
+ struct fsm_decode *dec)
{
+ /* Deal with incoming data */
+ struct ccp *ccp = fsm2ccp(fp);
int type, length;
int f;
-
- ackp = AckBuff;
- nakp = NakBuff;
- rejp = RejBuff;
+ 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 == 0) {
+ log_Printf(LogCCP, "%s: CCP size zero\n", fp->link->name);
+ break;
+ }
+
+ if (length > sizeof(struct lcp_opt)) {
+ length = sizeof(struct lcp_opt);
+ log_Printf(LogCCP, "%s: Warning: Truncating length to %d\n",
+ fp->link->name, 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)
+ log_Printf(LogCCP, " %s[%d] %s\n", cftypes[type], length, end);
+ else
+ log_Printf(LogCCP, " ???[%d] %s\n", length, end);
+
if (f == -1) {
/* Don't understand that :-( */
if (mode_type == MODE_REQ) {
- CcpInfo.my_reject |= (1 << type);
- memcpy(rejp, cp, length);
- rejp += length;
+ ccp->my_reject |= (1 << type);
+ memcpy(dec->rejend, cp, length);
+ dec->rejend += length;
}
} else {
- struct lcp_opt o;
+ struct ccp_opt *o;
switch (mode_type) {
case MODE_REQ:
- if (Acceptable(algorithm[f]->Conf) && in_algorithm == -1) {
- memcpy(&o, cp, length);
- switch ((*algorithm[f]->i.Set)(&o)) {
+ if (IsAccepted(ccp->cfg.neg[algorithm[f]->Neg]) &&
+ ccp->in.algorithm == -1) {
+ memcpy(&ccp->in.opt, cp, length);
+ switch ((*algorithm[f]->i.Set)(&ccp->in.opt, &ccp->cfg)) {
case MODE_REJ:
- memcpy(rejp, &o, o.len);
- rejp += o.len;
+ memcpy(dec->rejend, &ccp->in.opt, ccp->in.opt.len);
+ dec->rejend += ccp->in.opt.len;
break;
case MODE_NAK:
- memcpy(nakp, &o, o.len);
- nakp += o.len;
+ memcpy(dec->nakend, &ccp->in.opt, ccp->in.opt.len);
+ dec->nakend += ccp->in.opt.len;
break;
case MODE_ACK:
- memcpy(ackp, cp, length);
- ackp += length;
- CcpInfo.his_proto = type;
- in_algorithm = f; /* This one'll do ! */
+ memcpy(dec->ackend, cp, length);
+ dec->ackend += length;
+ ccp->his_proto = type;
+ ccp->in.algorithm = f; /* This one'll do :-) */
break;
}
} else {
- memcpy(rejp, cp, length);
- rejp += length;
+ memcpy(dec->rejend, cp, length);
+ dec->rejend += length;
}
break;
case MODE_NAK:
- memcpy(&o, cp, length);
- if ((*algorithm[f]->o.Set)(&o) == MODE_ACK)
- CcpInfo.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)
+ log_Printf(LogCCP, "%s: Warning: Ignoring peer NAK of unsent option\n",
+ fp->link->name);
else {
- CcpInfo.his_reject |= (1 << type);
- CcpInfo.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:
- CcpInfo.his_reject |= (1 << type);
- CcpInfo.my_proto = -1;
+ ccp->his_reject |= (1 << type);
+ ccp->my_proto = -1;
break;
}
}
- plen -= length;
- cp += length;
+ plen -= cp[1];
+ cp += cp[1];
}
- if (rejp != RejBuff) {
- ackp = AckBuff; /* let's not send both ! */
- CcpInfo.his_proto = -1;
- in_algorithm = -1;
+ if (mode_type != MODE_NOP) {
+ if (dec->rejend != dec->rej) {
+ /* rejects are preferred */
+ dec->ackend = dec->ack;
+ dec->nakend = dec->nak;
+ if (ccp->in.state == NULL) {
+ ccp->his_proto = -1;
+ ccp->in.algorithm = -1;
+ }
+ } else if (dec->nakend != dec->nak) {
+ /* then NAKs */
+ dec->ackend = dec->ack;
+ if (ccp->in.state == NULL) {
+ ccp->his_proto = -1;
+ ccp->in.algorithm = -1;
+ }
+ }
}
}
void
-CcpInput(struct mbuf *bp)
+ccp_Input(struct ccp *ccp, struct bundle *bundle, struct mbuf *bp)
{
- if (phase == PHASE_NETWORK)
- FsmInput(&CcpFsm, bp);
+ /* Got PROTO_CCP from link */
+ if (bundle_Phase(bundle) == PHASE_NETWORK)
+ fsm_Input(&ccp->fsm, bp);
else {
- if (phase > PHASE_NETWORK)
- LogPrintf(LogCCP, "Error: Unexpected CCP in phase %d\n", phase);
- pfree(bp);
+ if (bundle_Phase(bundle) < PHASE_NETWORK)
+ log_Printf(LogCCP, "%s: Error: Unexpected CCP in phase %s (ignored)\n",
+ ccp->fsm.link->name, bundle_PhaseName(bundle));
+ mbuf_Free(bp);
}
}
-void
-CcpResetInput(u_char id)
+static void
+CcpRecvResetAck(struct fsm *fp, u_char id)
{
- if (CcpInfo.reset_sent != -1) {
- if (id != CcpInfo.reset_sent) {
- LogPrintf(LogWARN, "CCP: Incorrect ResetAck (id %d, not %d) ignored\n",
- id, CcpInfo.reset_sent);
+ /* Got a reset ACK, reset incoming dictionary */
+ struct ccp *ccp = fsm2ccp(fp);
+
+ if (ccp->reset_sent != -1) {
+ if (id != ccp->reset_sent) {
+ log_Printf(LogWARN, "CCP: %s: Incorrect ResetAck (id %d, not %d)"
+ " ignored\n", fp->link->name, id, ccp->reset_sent);
return;
}
/* Whaddaya know - a correct reset ack */
- } else if (id == CcpInfo.last_reset)
- LogPrintf(LogCCP, "Duplicate ResetAck (resetting again)\n");
+ } else if (id == ccp->last_reset)
+ log_Printf(LogCCP, "%s: Duplicate ResetAck (resetting again)\n",
+ fp->link->name);
else {
- LogPrintf(LogWARN, "CCP: Unexpected ResetAck (id %d) ignored\n", id);
+ log_Printf(LogWARN, "CCP: %s: Unexpected ResetAck (id %d) ignored\n",
+ fp->link->name, id);
return;
}
- CcpInfo.last_reset = CcpInfo.reset_sent;
- CcpInfo.reset_sent = -1;
- if (in_algorithm >= 0 && in_algorithm < NALGORITHMS)
- (*algorithm[in_algorithm]->i.Reset)();
+ ccp->last_reset = ccp->reset_sent;
+ ccp->reset_sent = -1;
+ if (ccp->in.state != NULL)
+ (*algorithm[ccp->in.algorithm]->i.Reset)(ccp->in.state);
}
int
-CcpOutput(int pri, u_short proto, struct mbuf *m)
+ccp_Compress(struct ccp *ccp, struct link *l, int pri, u_short proto,
+ struct mbuf *m)
{
- if (out_algorithm >= 0 && out_algorithm < NALGORITHMS)
- return (*algorithm[out_algorithm]->o.Write)(pri, proto, m);
+ /*
+ * 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;
}
struct mbuf *
-CompdInput(u_short *proto, struct mbuf *m)
+ccp_Decompress(struct ccp *ccp, u_short *proto, struct mbuf *bp)
{
- if (CcpInfo.reset_sent != -1) {
- /* Send another REQ and put the packet in the bit bucket */
- LogPrintf(LogCCP, "ReSendResetReq(%d)\n", CcpInfo.reset_sent);
- FsmOutput(&CcpFsm, CODE_RESETREQ, CcpInfo.reset_sent, NULL, 0);
- } else if (in_algorithm >= 0 && in_algorithm < NALGORITHMS)
- return (*algorithm[in_algorithm]->i.Read)(proto, m);
- pfree(m);
- return NULL;
+ /*
+ * If proto isn't PROTO_[I]COMPD, we still want to pass it to the
+ * decompression routines so that the dictionary's updated
+ */
+ if (ccp->fsm.state == ST_OPENED) {
+ if (*proto == PROTO_COMPD || *proto == PROTO_ICOMPD) {
+ /* Decompress incoming data */
+ if (ccp->reset_sent != -1)
+ /* Send another REQ and put the packet in the bit bucket */
+ fsm_Output(&ccp->fsm, CODE_RESETREQ, ccp->reset_sent, NULL, 0);
+ else if (ccp->in.state != NULL)
+ return (*algorithm[ccp->in.algorithm]->i.Read)
+ (ccp->in.state, ccp, proto, bp);
+ mbuf_Free(bp);
+ bp = 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);
+ }
+
+ return bp;
}
-void
-CcpDictSetup(u_short proto, struct mbuf *m)
+u_short
+ccp_Proto(struct ccp *ccp)
{
- if (in_algorithm >= 0 && in_algorithm < NALGORITHMS)
- (*algorithm[in_algorithm]->i.DictSetup)(proto, m);
+ return !link2physical(ccp->fsm.link) || !ccp->fsm.bundle->ncp.mp.active ?
+ PROTO_COMPD : PROTO_ICOMPD;
}
OpenPOWER on IntegriCloud