ccp.c revision 13760
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 *
2013760Sphk * $Id: ccp.c,v 1.5 1996/01/11 17:48:37 phk 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"
306059Samurai#include "vars.h"
3113389Sphk#include "pred.h"
326735Samurai#include "cdefs.h"
338857Srgrimes
346735Samuraiextern void PutConfValue __P((void));
356059Samurai
366059Samuraistruct ccpstate CcpInfo;
376059Samurai
386735Samuraistatic void CcpSendConfigReq __P((struct fsm *));
396735Samuraistatic void CcpSendTerminateReq __P((struct fsm *fp));
406735Samuraistatic void CcpSendTerminateAck __P((struct fsm *fp));
416735Samuraistatic void CcpDecodeConfig __P((u_char *cp, int flen, int mode));
426735Samuraistatic void CcpLayerStart __P((struct fsm *));
436735Samuraistatic void CcpLayerFinish __P((struct fsm *));
446735Samuraistatic void CcpLayerUp __P((struct fsm *));
456735Samuraistatic void CcpLayerDown __P((struct fsm *));
466735Samuraistatic void CcpInitRestartCounter __P((struct fsm *));
476059Samurai
486059Samurai#define	REJECTED(p, x)	(p->his_reject & (1<<x))
496059Samurai
506059Samuraistruct fsm CcpFsm = {
516059Samurai  "CCP",
526059Samurai  PROTO_CCP,
536059Samurai  CCP_MAXCODE,
546059Samurai  OPEN_ACTIVE,
556059Samurai  ST_INITIAL,
566059Samurai  0, 0, 0,
576059Samurai
586059Samurai  0,
596059Samurai  { 0, 0, 0, NULL, NULL, NULL },
606059Samurai
616059Samurai  CcpLayerUp,
626059Samurai  CcpLayerDown,
636059Samurai  CcpLayerStart,
646059Samurai  CcpLayerFinish,
656059Samurai  CcpInitRestartCounter,
666059Samurai  CcpSendConfigReq,
676059Samurai  CcpSendTerminateReq,
686059Samurai  CcpSendTerminateAck,
696059Samurai  CcpDecodeConfig,
706059Samurai};
716059Samurai
7213760Sphkstatic char const *cftypes[] = {
736059Samurai/*  0 */  "OUI",    "PRED1", "PRED2", "PUDDLE",
746059Samurai/*  4 */  "???",    "???",   "???",   "???",
756059Samurai/*  8 */  "???",    "???",   "???",   "???",
766059Samurai/* 12 */  "???",    "???",   "???",   "???",
776059Samurai/* 16 */  "HWPPC",  "STAC",  "MSPPC", "GAND",
786059Samurai/* 20 */  "V42BIS", "BSD",
796059Samurai};
806059Samurai
816059Samuraivoid
826059SamuraiReportCcpStatus()
836059Samurai{
846059Samurai  struct ccpstate *icp = &CcpInfo;
856059Samurai  struct fsm *fp = &CcpFsm;
866059Samurai
876059Samurai  printf("%s [%s]\n", fp->name, StateNames[fp->state]);
886059Samurai  printf("myproto = %s, hisproto = %s\n",
896059Samurai	cftypes[icp->want_proto], cftypes[icp->his_proto]);
9013379Sphk  printf("Input: %ld --> %ld,  Output: %ld --> %ld\n",
916059Samurai	icp->orgin, icp->compin, icp->orgout, icp->compout);
926059Samurai}
936059Samurai
946059Samuraivoid
956059SamuraiCcpInit()
966059Samurai{
976059Samurai  struct ccpstate *icp = &CcpInfo;
986059Samurai
996059Samurai  FsmInit(&CcpFsm);
1006059Samurai  bzero(icp, sizeof(struct ccpstate));
1016059Samurai  if (Enabled(ConfPred1))
1026059Samurai    icp->want_proto = TY_PRED1;
1036059Samurai  CcpFsm.maxconfig = 10;
1046059Samurai}
1056059Samurai
1066059Samuraistatic void
1076059SamuraiCcpInitRestartCounter(fp)
1086059Samuraistruct fsm *fp;
1096059Samurai{
1106735Samurai  fp->FsmTimer.load = VarRetryTimeout * SECTICKS;
1116059Samurai  fp->restart = 5;
1126059Samurai}
1136059Samurai
1146059Samuraistatic void
1156059SamuraiCcpSendConfigReq(fp)
1166059Samuraistruct fsm *fp;
1176059Samurai{
1186059Samurai  u_char *cp;
1196059Samurai  struct ccpstate *icp = &CcpInfo;
1206059Samurai
1216059Samurai  cp = ReqBuff;
1226059Samurai  LogPrintf(LOG_LCP, "%s: SendConfigReq\n", fp->name);
1236059Samurai  if (icp->want_proto && !REJECTED(icp, TY_PRED1)) {
1246059Samurai    *cp++ = TY_PRED1; *cp++ = 2;
1256059Samurai  }
1266059Samurai  FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff);
1276059Samurai}
1286059Samurai
1296059Samuraivoid
1306059SamuraiCcpSendResetReq(fp)
1316059Samuraistruct fsm *fp;
1326059Samurai{
1336059Samurai  Pred1Init(1);		/* Initialize Input part */
1346059Samurai  LogPrintf(LOG_LCP, "%s: SendResetReq\n", fp->name);
1356059Samurai  FsmOutput(fp, CODE_RESETREQ, fp->reqid, NULL, 0);
1366059Samurai}
1376059Samurai
1386059Samuraistatic void
1396059SamuraiCcpSendTerminateReq(fp)
1406059Samuraistruct fsm *fp;
1416059Samurai{
1426059Samurai  /* XXX: No code yet */
1436059Samurai}
1446059Samurai
1456059Samuraistatic void
1466059SamuraiCcpSendTerminateAck(fp)
1476059Samuraistruct fsm *fp;
1486059Samurai{
1496059Samurai  LogPrintf(LOG_LCP, "  %s: SendTerminateAck\n", fp->name);
1506059Samurai  FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0);
1516059Samurai}
1526059Samurai
1536059Samuraivoid
1546059SamuraiCcpRecvResetReq(fp)
1556059Samuraistruct fsm *fp;
1566059Samurai{
1576059Samurai  Pred1Init(2);		/* Initialize Output part */
1586059Samurai}
1596059Samurai
1606059Samuraistatic void
1616059SamuraiCcpLayerStart(fp)
1626059Samuraistruct fsm *fp;
1636059Samurai{
1646059Samurai  LogPrintf(LOG_LCP, "%s: LayerStart.\n", fp->name);
1656059Samurai}
1666059Samurai
1676059Samuraistatic void
1686059SamuraiCcpLayerFinish(fp)
1696059Samuraistruct fsm *fp;
1706059Samurai{
1716059Samurai  LogPrintf(LOG_LCP, "%s: LayerFinish.\n", fp->name);
1726059Samurai}
1736059Samurai
1746059Samuraistatic void
1756059SamuraiCcpLayerDown(fp)
1766059Samuraistruct fsm *fp;
1776059Samurai{
1786059Samurai  LogPrintf(LOG_LCP, "%s: LayerDown.\n", fp->name);
1796059Samurai}
1806059Samurai
1816059Samurai/*
1826059Samurai *  Called when CCP has reached to OPEN state
1836059Samurai */
1846059Samuraistatic void
1856059SamuraiCcpLayerUp(fp)
1866059Samuraistruct fsm *fp;
1876059Samurai{
1886059Samurai#ifdef VERBOSE
1896059Samurai  fprintf(stderr, "%s: LayerUp(%d).\r\n", fp->name, fp->state);
1906059Samurai#endif
1916059Samurai  LogPrintf(LOG_LCP, "%s: LayerUp.\n", fp->name);
1926059Samurai  LogPrintf(LOG_LCP, "myproto = %d, hisproto = %d\n",
1936059Samurai	CcpInfo.want_proto, CcpInfo.his_proto);
1946059Samurai  Pred1Init(3);		/* Initialize Input and Output */
1956059Samurai}
1966059Samurai
1976059Samuraivoid
1986059SamuraiCcpUp()
1996059Samurai{
2006059Samurai  FsmUp(&CcpFsm);
2016059Samurai  LogPrintf(LOG_LCP, "CCP Up event!!\n");
2026059Samurai}
2036059Samurai
2046059Samuraivoid
2056059SamuraiCcpOpen()
2066059Samurai{
2076059Samurai  if (Enabled(ConfPred1))
2086059Samurai    FsmOpen(&CcpFsm);
2096059Samurai}
2106059Samurai
2116059Samuraistatic void
2126735SamuraiCcpDecodeConfig(cp, plen, mode)
2136735Samuraiu_char *cp;
2146735Samuraiint plen;
2156059Samuraiint mode;
2166059Samurai{
2176735Samurai  int type, length;
2186059Samurai  char tbuff[100];
2196059Samurai
2206059Samurai  ackp = AckBuff;
2216059Samurai  nakp = NakBuff;
2226059Samurai  rejp = RejBuff;
2236059Samurai
2246059Samurai  while (plen >= sizeof(struct fsmconfig)) {
2256059Samurai    if (plen < 0)
2266059Samurai      break;
2276059Samurai    type = *cp;
2286059Samurai    length = cp[1];
2296059Samurai    if (type <= TY_BSD)
2306059Samurai      sprintf(tbuff, " %s[%d] ", cftypes[type], length);
2316059Samurai    else
2326059Samurai      sprintf(tbuff, " ");
2336059Samurai
2346059Samurai    LogPrintf(LOG_LCP, "%s\n", tbuff);
2356059Samurai
2366059Samurai    switch (type) {
2376059Samurai    case TY_PRED1:
2386059Samurai      switch (mode) {
2396059Samurai      case MODE_REQ:
2406059Samurai	if (Acceptable(ConfPred1)) {
2416059Samurai	  bcopy(cp, ackp, length);
2426059Samurai	  ackp += length;
2436059Samurai	  CcpInfo.his_proto = type;
2446059Samurai	} else {
2456059Samurai	  bcopy(cp, rejp, length);
2466059Samurai	  rejp += length;
2476059Samurai	}
2486059Samurai	break;
2496059Samurai      case MODE_NAK:
2506059Samurai      case MODE_REJ:
2516059Samurai	CcpInfo.his_reject |= (1 << type);
2526059Samurai	CcpInfo.want_proto = 0;
2536059Samurai	break;
2546059Samurai      }
2556059Samurai      break;
2566059Samurai    case TY_BSD:
2576059Samurai    default:
2586059Samurai      CcpInfo.my_reject |= (1 << type);
2596059Samurai      bcopy(cp, rejp, length);
2606059Samurai      rejp += length;
2616059Samurai      break;
2626059Samurai    }
2636059Samurai    plen -= length;
2646059Samurai    cp += length;
2656059Samurai  }
2666059Samurai}
2676059Samurai
2686059Samuraivoid
2696059SamuraiCcpInput(struct mbuf *bp)
2706059Samurai{
2716059Samurai  if (phase == PHASE_NETWORK)
2726059Samurai    FsmInput(&CcpFsm, bp);
2736059Samurai  else {
2746059Samurai    logprintf("ccp in phase %d\n", phase);
2756059Samurai    pfree(bp);
2766059Samurai  }
2776059Samurai}
278