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