ccp.c revision 29294
16059Samurai/*
26059Samurai *	   PPP Compression Control Protocol (CCP) Module
36059Samurai *
46059Samurai *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
56059Samurai *
66059Samurai *   Copyright (C) 1994, Internet Initiative Japan, Inc. All rights reserverd.
76059Samurai *
86059Samurai * Redistribution and use in source and binary forms are permitted
96059Samurai * provided that the above copyright notice and this paragraph are
106059Samurai * duplicated in all such forms and that any documentation,
116059Samurai * advertising materials, and other materials related to such
126059Samurai * distribution and use acknowledge that the software was developed
136059Samurai * by the Internet Initiative Japan, Inc.  The name of the
146059Samurai * IIJ may not be used to endorse or promote products derived
156059Samurai * from this software without specific prior written permission.
166059Samurai * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
176059Samurai * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
186059Samurai * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
198857Srgrimes *
2029294Sbrian * $Id: ccp.c,v 1.15 1997/08/25 00:29:06 brian Exp $
218857Srgrimes *
226059Samurai *	TODO:
236059Samurai *		o Support other compression protocols
246059Samurai */
256059Samurai#include "fsm.h"
266059Samurai#include "lcpproto.h"
276059Samurai#include "lcp.h"
286059Samurai#include "ccp.h"
296059Samurai#include "phase.h"
3026142Sbrian#include "loadalias.h"
316059Samurai#include "vars.h"
3213389Sphk#include "pred.h"
338857Srgrimes
346059Samuraistruct ccpstate CcpInfo;
356059Samurai
3626516Sbrianstatic void CcpSendConfigReq(struct fsm *);
3728679Sbrianstatic void CcpSendTerminateReq(struct fsm * fp);
3828679Sbrianstatic void CcpSendTerminateAck(struct fsm * fp);
3928679Sbrianstatic void CcpDecodeConfig(u_char * cp, int flen, int mode);
4026516Sbrianstatic void CcpLayerStart(struct fsm *);
4126516Sbrianstatic void CcpLayerFinish(struct fsm *);
4226516Sbrianstatic void CcpLayerUp(struct fsm *);
4326516Sbrianstatic void CcpLayerDown(struct fsm *);
4426516Sbrianstatic void CcpInitRestartCounter(struct fsm *);
456059Samurai
466059Samurai#define	REJECTED(p, x)	(p->his_reject & (1<<x))
476059Samurai
486059Samuraistruct fsm CcpFsm = {
496059Samurai  "CCP",
506059Samurai  PROTO_CCP,
516059Samurai  CCP_MAXCODE,
526059Samurai  OPEN_ACTIVE,
536059Samurai  ST_INITIAL,
546059Samurai  0, 0, 0,
556059Samurai  0,
5628679Sbrian  {0, 0, 0, NULL, NULL, NULL},
5728679Sbrian  {0, 0, 0, NULL, NULL, NULL},
5828461Sbrian  LogCCP,
596059Samurai
606059Samurai  CcpLayerUp,
616059Samurai  CcpLayerDown,
626059Samurai  CcpLayerStart,
636059Samurai  CcpLayerFinish,
646059Samurai  CcpInitRestartCounter,
656059Samurai  CcpSendConfigReq,
666059Samurai  CcpSendTerminateReq,
676059Samurai  CcpSendTerminateAck,
686059Samurai  CcpDecodeConfig,
696059Samurai};
706059Samurai
7113760Sphkstatic char const *cftypes[] = {
7228679Sbrian   /*  0 */ "OUI", "PRED1", "PRED2", "PUDDLE",
7328679Sbrian   /*  4 */ "???", "???", "???", "???",
7428679Sbrian   /*  8 */ "???", "???", "???", "???",
7528679Sbrian   /* 12 */ "???", "???", "???", "???",
7628679Sbrian   /* 16 */ "HWPPC", "STAC", "MSPPC", "GAND",
7728679Sbrian   /* 20 */ "V42BIS", "BSD",
786059Samurai};
796059Samurai
8025630Sbrianint
816059SamuraiReportCcpStatus()
826059Samurai{
836059Samurai  struct ccpstate *icp = &CcpInfo;
846059Samurai  struct fsm *fp = &CcpFsm;
856059Samurai
8626516Sbrian  if (VarTerm) {
8726516Sbrian    fprintf(VarTerm, "%s [%s]\n", fp->name, StateNames[fp->state]);
8826516Sbrian    fprintf(VarTerm, "myproto = %s, hisproto = %s\n",
8926516Sbrian	    cftypes[icp->want_proto], cftypes[icp->his_proto]);
9026516Sbrian    fprintf(VarTerm, "Input: %ld --> %ld,  Output: %ld --> %ld\n",
9126516Sbrian	    icp->orgin, icp->compin, icp->orgout, icp->compout);
9226516Sbrian  }
9325630Sbrian  return 0;
946059Samurai}
956059Samurai
966059Samuraivoid
976059SamuraiCcpInit()
986059Samurai{
996059Samurai  struct ccpstate *icp = &CcpInfo;
1006059Samurai
1016059Samurai  FsmInit(&CcpFsm);
1026059Samurai  bzero(icp, sizeof(struct ccpstate));
1036059Samurai  if (Enabled(ConfPred1))
1046059Samurai    icp->want_proto = TY_PRED1;
1056059Samurai  CcpFsm.maxconfig = 10;
1066059Samurai}
1076059Samurai
1086059Samuraistatic void
10928679SbrianCcpInitRestartCounter(struct fsm * fp)
1106059Samurai{
1116735Samurai  fp->FsmTimer.load = VarRetryTimeout * SECTICKS;
1126059Samurai  fp->restart = 5;
1136059Samurai}
1146059Samurai
1156059Samuraistatic void
11628679SbrianCcpSendConfigReq(struct fsm * fp)
1176059Samurai{
1186059Samurai  u_char *cp;
1196059Samurai  struct ccpstate *icp = &CcpInfo;
1206059Samurai
1216059Samurai  cp = ReqBuff;
12228461Sbrian  LogPrintf(LogCCP, "CcpSendConfigReq\n");
1236059Samurai  if (icp->want_proto && !REJECTED(icp, TY_PRED1)) {
12428679Sbrian    *cp++ = TY_PRED1;
12528679Sbrian    *cp++ = 2;
1266059Samurai  }
1276059Samurai  FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff);
1286059Samurai}
1296059Samurai
1306059Samuraivoid
13128679SbrianCcpSendResetReq(struct fsm * fp)
1326059Samurai{
13328461Sbrian  LogPrintf(LogCCP, "CcpSendResetReq\n");
1346059Samurai  FsmOutput(fp, CODE_RESETREQ, fp->reqid, NULL, 0);
1356059Samurai}
1366059Samurai
1376059Samuraistatic void
13828679SbrianCcpSendTerminateReq(struct fsm * fp)
1396059Samurai{
1406059Samurai  /* XXX: No code yet */
1416059Samurai}
1426059Samurai
1436059Samuraistatic void
14428679SbrianCcpSendTerminateAck(struct fsm * fp)
1456059Samurai{
14628461Sbrian  LogPrintf(LogCCP, "CcpSendTerminateAck\n");
1476059Samurai  FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0);
1486059Samurai}
1496059Samurai
1506059Samuraivoid
15128679SbrianCcpRecvResetReq(struct fsm * fp)
1526059Samurai{
15328679Sbrian  Pred1Init(2);			/* Initialize Output part */
1546059Samurai}
1556059Samurai
1566059Samuraistatic void
15728679SbrianCcpLayerStart(struct fsm * fp)
1586059Samurai{
15928461Sbrian  LogPrintf(LogCCP, "CcpLayerStart.\n");
1606059Samurai}
1616059Samurai
1626059Samuraistatic void
16328679SbrianCcpLayerFinish(struct fsm * fp)
1646059Samurai{
16528461Sbrian  LogPrintf(LogCCP, "CcpLayerFinish.\n");
1666059Samurai}
1676059Samurai
1686059Samuraistatic void
16928679SbrianCcpLayerDown(struct fsm * fp)
1706059Samurai{
17128461Sbrian  LogPrintf(LogCCP, "CcpLayerDown.\n");
1726059Samurai}
1736059Samurai
1746059Samurai/*
1756059Samurai *  Called when CCP has reached to OPEN state
1766059Samurai */
1776059Samuraistatic void
17828679SbrianCcpLayerUp(struct fsm * fp)
1796059Samurai{
18028461Sbrian  LogPrintf(LogCCP, "CcpLayerUp(%d).\n", fp->state);
18128461Sbrian  LogPrintf(LogCCP, "myproto = %d, hisproto = %d\n",
18228679Sbrian	    CcpInfo.want_proto, CcpInfo.his_proto);
18328679Sbrian  Pred1Init(3);			/* Initialize Input and Output */
1846059Samurai}
1856059Samurai
1866059Samuraivoid
1876059SamuraiCcpUp()
1886059Samurai{
1896059Samurai  FsmUp(&CcpFsm);
19028461Sbrian  LogPrintf(LogCCP, "CCP Up event!!\n");
1916059Samurai}
1926059Samurai
1936059Samuraivoid
1946059SamuraiCcpOpen()
1956059Samurai{
1966059Samurai  if (Enabled(ConfPred1))
1976059Samurai    FsmOpen(&CcpFsm);
1986059Samurai}
1996059Samurai
2006059Samuraistatic void
20128679SbrianCcpDecodeConfig(u_char * cp, int plen, int mode)
2026059Samurai{
2036735Samurai  int type, length;
2046059Samurai  char tbuff[100];
2056059Samurai
2066059Samurai  ackp = AckBuff;
2076059Samurai  nakp = NakBuff;
2086059Samurai  rejp = RejBuff;
2096059Samurai
2106059Samurai  while (plen >= sizeof(struct fsmconfig)) {
2116059Samurai    if (plen < 0)
2126059Samurai      break;
2136059Samurai    type = *cp;
2146059Samurai    length = cp[1];
2156059Samurai    if (type <= TY_BSD)
21621488Simp      snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes[type], length);
2176059Samurai    else
21821488Simp      snprintf(tbuff, sizeof(tbuff), " ");
2196059Samurai
22028461Sbrian    LogPrintf(LogCCP, "%s\n", tbuff);
2216059Samurai
2226059Samurai    switch (type) {
2236059Samurai    case TY_PRED1:
2246059Samurai      switch (mode) {
2256059Samurai      case MODE_REQ:
2266059Samurai	if (Acceptable(ConfPred1)) {
2276059Samurai	  bcopy(cp, ackp, length);
2286059Samurai	  ackp += length;
2296059Samurai	  CcpInfo.his_proto = type;
2306059Samurai	} else {
2316059Samurai	  bcopy(cp, rejp, length);
2326059Samurai	  rejp += length;
2336059Samurai	}
2346059Samurai	break;
2356059Samurai      case MODE_NAK:
2366059Samurai      case MODE_REJ:
2376059Samurai	CcpInfo.his_reject |= (1 << type);
2386059Samurai	CcpInfo.want_proto = 0;
2396059Samurai	break;
2406059Samurai      }
2416059Samurai      break;
2426059Samurai    case TY_BSD:
2436059Samurai    default:
2446059Samurai      CcpInfo.my_reject |= (1 << type);
2456059Samurai      bcopy(cp, rejp, length);
2466059Samurai      rejp += length;
2476059Samurai      break;
2486059Samurai    }
2496059Samurai    plen -= length;
2506059Samurai    cp += length;
2516059Samurai  }
2526059Samurai}
2536059Samurai
2546059Samuraivoid
25528679SbrianCcpInput(struct mbuf * bp)
2566059Samurai{
2576059Samurai  if (phase == PHASE_NETWORK)
2586059Samurai    FsmInput(&CcpFsm, bp);
2596059Samurai  else {
26029294Sbrian    if (phase > PHASE_NETWORK)
26129294Sbrian      LogPrintf(LogERROR, "Unexpected CCP in phase %d\n", phase);
2626059Samurai    pfree(bp);
2636059Samurai  }
2646059Samurai}
265