1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-29 12:03:03 +00:00
freebsd/usr.sbin/ppp/ccp.c

285 lines
6.2 KiB
C
Raw Normal View History

1995-01-31 06:29:58 +00:00
/*
* PPP Compression Control Protocol (CCP) Module
*
* Written by Toshiharu OHNO (tony-o@iij.ad.jp)
*
* Copyright (C) 1994, Internet Initiative Japan, Inc. All rights reserverd.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the Internet Initiative Japan, Inc. The name of the
* IIJ may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1995-05-30 03:57:47 +00:00
*
* $Id: ccp.c,v 1.18 1997/11/08 00:28:06 brian Exp $
1995-05-30 03:57:47 +00:00
*
1995-01-31 06:29:58 +00:00
* TODO:
* o Support other compression protocols
*/
#include <sys/param.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include "mbuf.h"
#include "log.h"
#include "defs.h"
#include "timer.h"
1995-01-31 06:29:58 +00:00
#include "fsm.h"
#include "lcpproto.h"
#include "lcp.h"
#include "ccp.h"
#include "phase.h"
#include "loadalias.h"
#include "command.h"
1995-01-31 06:29:58 +00:00
#include "vars.h"
#include "pred.h"
1995-05-30 03:57:47 +00:00
1995-01-31 06:29:58 +00:00
struct ccpstate CcpInfo;
static void CcpSendConfigReq(struct fsm *);
static void CcpSendTerminateReq(struct fsm *);
static void CcpSendTerminateAck(struct fsm *);
static void CcpDecodeConfig(u_char *, int, int);
static void CcpLayerStart(struct fsm *);
static void CcpLayerFinish(struct fsm *);
static void CcpLayerUp(struct fsm *);
static void CcpLayerDown(struct fsm *);
static void CcpInitRestartCounter(struct fsm *);
1995-01-31 06:29:58 +00:00
#define REJECTED(p, x) (p->his_reject & (1<<x))
struct fsm CcpFsm = {
"CCP",
PROTO_CCP,
CCP_MAXCODE,
OPEN_ACTIVE,
ST_INITIAL,
0, 0, 0,
0,
{0, 0, 0, NULL, NULL, NULL},
{0, 0, 0, NULL, NULL, NULL},
LogCCP,
1995-01-31 06:29:58 +00:00
CcpLayerUp,
CcpLayerDown,
CcpLayerStart,
CcpLayerFinish,
CcpInitRestartCounter,
CcpSendConfigReq,
CcpSendTerminateReq,
CcpSendTerminateAck,
CcpDecodeConfig,
};
static char const *cftypes[] = {
/* Check out the latest ``Compression Control Protocol'' rfc (rfc1962.txt) */
"OUI", /* 0: OUI */
"PRED1", /* 1: Predictor type 1 */
"PRED2", /* 2: Predictor type 2 */
"PUDDLE", /* 3: Puddle Jumber */
"???", "???", "???", "???", "???", "???",
"???", "???", "???", "???", "???", "???",
"HWPPC", /* 16: Hewlett-Packard PPC */
"STAC", /* 17: Stac Electronics LZS */
"MSPPC", /* 18: Microsoft PPC */
"GAND", /* 19: Gandalf FZA */
"V42BIS", /* 20: V.42bis compression */
"BSD", /* BSD LZW Compress */
1995-01-31 06:29:58 +00:00
};
#define NCFTYPES (sizeof(cftypes)/sizeof(char *))
int
1995-01-31 06:29:58 +00:00
ReportCcpStatus()
{
struct ccpstate *icp = &CcpInfo;
struct fsm *fp = &CcpFsm;
if (VarTerm) {
fprintf(VarTerm, "%s [%s]\n", fp->name, StateNames[fp->state]);
fprintf(VarTerm, "myproto = %s, hisproto = %s\n",
cftypes[icp->want_proto], cftypes[icp->his_proto]);
fprintf(VarTerm, "Input: %ld --> %ld, Output: %ld --> %ld\n",
icp->orgin, icp->compin, icp->orgout, icp->compout);
}
return 0;
1995-01-31 06:29:58 +00:00
}
void
CcpInit()
{
struct ccpstate *icp = &CcpInfo;
FsmInit(&CcpFsm);
memset(icp, '\0', sizeof(struct ccpstate));
1995-01-31 06:29:58 +00:00
if (Enabled(ConfPred1))
icp->want_proto = TY_PRED1;
CcpFsm.maxconfig = 10;
}
static void
CcpInitRestartCounter(struct fsm *fp)
1995-01-31 06:29:58 +00:00
{
fp->FsmTimer.load = VarRetryTimeout * SECTICKS;
1995-01-31 06:29:58 +00:00
fp->restart = 5;
}
static void
CcpSendConfigReq(struct fsm *fp)
1995-01-31 06:29:58 +00:00
{
u_char *cp;
struct ccpstate *icp = &CcpInfo;
cp = ReqBuff;
LogPrintf(LogCCP, "CcpSendConfigReq\n");
1995-01-31 06:29:58 +00:00
if (icp->want_proto && !REJECTED(icp, TY_PRED1)) {
*cp++ = TY_PRED1;
*cp++ = 2;
1995-01-31 06:29:58 +00:00
}
FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff);
}
void
CcpSendResetReq(struct fsm *fp)
1995-01-31 06:29:58 +00:00
{
LogPrintf(LogCCP, "CcpSendResetReq\n");
1995-01-31 06:29:58 +00:00
FsmOutput(fp, CODE_RESETREQ, fp->reqid, NULL, 0);
}
static void
CcpSendTerminateReq(struct fsm *fp)
1995-01-31 06:29:58 +00:00
{
/* XXX: No code yet */
}
static void
CcpSendTerminateAck(struct fsm *fp)
1995-01-31 06:29:58 +00:00
{
LogPrintf(LogCCP, "CcpSendTerminateAck\n");
1995-01-31 06:29:58 +00:00
FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0);
}
void
CcpRecvResetReq(struct fsm *fp)
1995-01-31 06:29:58 +00:00
{
Pred1Init(2); /* Initialize Output part */
1995-01-31 06:29:58 +00:00
}
static void
CcpLayerStart(struct fsm *fp)
1995-01-31 06:29:58 +00:00
{
LogPrintf(LogCCP, "CcpLayerStart.\n");
1995-01-31 06:29:58 +00:00
}
static void
CcpLayerFinish(struct fsm *fp)
1995-01-31 06:29:58 +00:00
{
LogPrintf(LogCCP, "CcpLayerFinish.\n");
1995-01-31 06:29:58 +00:00
}
static void
CcpLayerDown(struct fsm *fp)
1995-01-31 06:29:58 +00:00
{
LogPrintf(LogCCP, "CcpLayerDown.\n");
1995-01-31 06:29:58 +00:00
}
/*
* Called when CCP has reached to OPEN state
*/
static void
CcpLayerUp(struct fsm *fp)
1995-01-31 06:29:58 +00:00
{
LogPrintf(LogCCP, "CcpLayerUp(%d).\n", fp->state);
LogPrintf(LogCCP, "myproto = %d, hisproto = %d\n",
CcpInfo.want_proto, CcpInfo.his_proto);
Pred1Init(3); /* Initialize Input and Output */
1995-01-31 06:29:58 +00:00
}
void
CcpUp()
{
FsmUp(&CcpFsm);
LogPrintf(LogCCP, "CCP Up event!!\n");
1995-01-31 06:29:58 +00:00
}
void
CcpOpen()
{
if (Enabled(ConfPred1))
FsmOpen(&CcpFsm);
}
static void
CcpDecodeConfig(u_char *cp, int plen, int mode_type)
1995-01-31 06:29:58 +00:00
{
int type, length;
1995-01-31 06:29:58 +00:00
char tbuff[100];
ackp = AckBuff;
nakp = NakBuff;
rejp = RejBuff;
while (plen >= sizeof(struct fsmconfig)) {
if (plen < 0)
break;
type = *cp;
length = cp[1];
if (type < NCFTYPES)
snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes[type], length);
1995-01-31 06:29:58 +00:00
else
snprintf(tbuff, sizeof(tbuff), " ");
1995-01-31 06:29:58 +00:00
LogPrintf(LogCCP, "%s\n", tbuff);
1995-01-31 06:29:58 +00:00
switch (type) {
case TY_PRED1:
switch (mode_type) {
1995-01-31 06:29:58 +00:00
case MODE_REQ:
if (Acceptable(ConfPred1)) {
memcpy(ackp, cp, length);
1995-01-31 06:29:58 +00:00
ackp += length;
CcpInfo.his_proto = type;
} else {
memcpy(rejp, cp, length);
1995-01-31 06:29:58 +00:00
rejp += length;
}
break;
case MODE_NAK:
case MODE_REJ:
CcpInfo.his_reject |= (1 << type);
CcpInfo.want_proto = 0;
break;
}
break;
case TY_BSD:
default:
CcpInfo.my_reject |= (1 << type);
memcpy(rejp, cp, length);
1995-01-31 06:29:58 +00:00
rejp += length;
break;
}
plen -= length;
cp += length;
}
}
void
CcpInput(struct mbuf *bp)
1995-01-31 06:29:58 +00:00
{
if (phase == PHASE_NETWORK)
FsmInput(&CcpFsm, bp);
else {
if (phase > PHASE_NETWORK)
LogPrintf(LogERROR, "Unexpected CCP in phase %d\n", phase);
1995-01-31 06:29:58 +00:00
pfree(bp);
}
}