ccp.c revision 28679
117680Spst/* 239300Sfenner * PPP Compression Control Protocol (CCP) Module 317680Spst * 417680Spst * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 517680Spst * 617680Spst * Copyright (C) 1994, Internet Initiative Japan, Inc. All rights reserverd. 717680Spst * 817680Spst * Redistribution and use in source and binary forms are permitted 917680Spst * provided that the above copyright notice and this paragraph are 1017680Spst * duplicated in all such forms and that any documentation, 1117680Spst * advertising materials, and other materials related to such 1217680Spst * distribution and use acknowledge that the software was developed 1317680Spst * by the Internet Initiative Japan, Inc. The name of the 1417680Spst * IIJ may not be used to endorse or promote products derived 1517680Spst * from this software without specific prior written permission. 1617680Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1717680Spst * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1817680Spst * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1917680Spst * 2056896Sfenner * $Id: ccp.c,v 1.14 1997/08/20 23:47:40 brian Exp $ 2156896Sfenner * 2217680Spst * TODO: 2317680Spst * o Support other compression protocols 2417680Spst */ 2526183Sfenner#include "fsm.h" 2656896Sfenner#include "lcpproto.h" 2717680Spst#include "lcp.h" 2817680Spst#include "ccp.h" 2956896Sfenner#include "phase.h" 3056896Sfenner#include "loadalias.h" 3156896Sfenner#include "vars.h" 3256896Sfenner#include "pred.h" 3317680Spst 3417680Spststruct ccpstate CcpInfo; 3517680Spst 3617680Spststatic void CcpSendConfigReq(struct fsm *); 3717680Spststatic void CcpSendTerminateReq(struct fsm * fp); 3817680Spststatic void CcpSendTerminateAck(struct fsm * fp); 3917680Spststatic void CcpDecodeConfig(u_char * cp, int flen, int mode); 4017680Spststatic void CcpLayerStart(struct fsm *); 4117680Spststatic void CcpLayerFinish(struct fsm *); 4217680Spststatic void CcpLayerUp(struct fsm *); 4317680Spststatic void CcpLayerDown(struct fsm *); 4421262Swollmanstatic void CcpInitRestartCounter(struct fsm *); 4517680Spst 4617680Spst#define REJECTED(p, x) (p->his_reject & (1<<x)) 4717680Spst 4817680Spststruct fsm CcpFsm = { 4917680Spst "CCP", 5017680Spst PROTO_CCP, 5117680Spst CCP_MAXCODE, 5239300Sfenner OPEN_ACTIVE, 5317680Spst ST_INITIAL, 5439300Sfenner 0, 0, 0, 5539300Sfenner 0, 5617680Spst {0, 0, 0, NULL, NULL, NULL}, 5739300Sfenner {0, 0, 0, NULL, NULL, NULL}, 5817680Spst LogCCP, 5917680Spst 6017680Spst CcpLayerUp, 6156896Sfenner CcpLayerDown, 6217680Spst CcpLayerStart, 6317680Spst CcpLayerFinish, 6417680Spst CcpInitRestartCounter, 6517680Spst CcpSendConfigReq, 6617680Spst CcpSendTerminateReq, 6717680Spst CcpSendTerminateAck, 6817680Spst CcpDecodeConfig, 6917680Spst}; 7017680Spst 7117680Spststatic char const *cftypes[] = { 7217680Spst /* 0 */ "OUI", "PRED1", "PRED2", "PUDDLE", 7317680Spst /* 4 */ "???", "???", "???", "???", 7417680Spst /* 8 */ "???", "???", "???", "???", 7517680Spst /* 12 */ "???", "???", "???", "???", 7617680Spst /* 16 */ "HWPPC", "STAC", "MSPPC", "GAND", 7717680Spst /* 20 */ "V42BIS", "BSD", 7817680Spst}; 7917680Spst 8017680Spstint 8117680SpstReportCcpStatus() 8217680Spst{ 8317680Spst struct ccpstate *icp = &CcpInfo; 8417680Spst struct fsm *fp = &CcpFsm; 8517680Spst 8617680Spst if (VarTerm) { 8717680Spst fprintf(VarTerm, "%s [%s]\n", fp->name, StateNames[fp->state]); 8817680Spst fprintf(VarTerm, "myproto = %s, hisproto = %s\n", 8917680Spst cftypes[icp->want_proto], cftypes[icp->his_proto]); 9017680Spst fprintf(VarTerm, "Input: %ld --> %ld, Output: %ld --> %ld\n", 9117680Spst icp->orgin, icp->compin, icp->orgout, icp->compout); 9217680Spst } 9317680Spst return 0; 9417680Spst} 9517680Spst 9617680Spstvoid 9717680SpstCcpInit() 9817680Spst{ 9917680Spst struct ccpstate *icp = &CcpInfo; 10017680Spst 10117680Spst FsmInit(&CcpFsm); 10217680Spst bzero(icp, sizeof(struct ccpstate)); 10317680Spst if (Enabled(ConfPred1)) 10417680Spst icp->want_proto = TY_PRED1; 10517680Spst CcpFsm.maxconfig = 10; 10617680Spst} 10717680Spst 10817680Spststatic void 10917680SpstCcpInitRestartCounter(struct fsm * fp) 11056896Sfenner{ 11156896Sfenner fp->FsmTimer.load = VarRetryTimeout * SECTICKS; 11256896Sfenner fp->restart = 5; 11356896Sfenner} 11456896Sfenner 11556896Sfennerstatic void 11656896SfennerCcpSendConfigReq(struct fsm * fp) 11756896Sfenner{ 11856896Sfenner u_char *cp; 11956896Sfenner struct ccpstate *icp = &CcpInfo; 12056896Sfenner 12156896Sfenner cp = ReqBuff; 12256896Sfenner LogPrintf(LogCCP, "CcpSendConfigReq\n"); 12356896Sfenner if (icp->want_proto && !REJECTED(icp, TY_PRED1)) { 12456896Sfenner *cp++ = TY_PRED1; 12556896Sfenner *cp++ = 2; 12656896Sfenner } 12756896Sfenner FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff); 12856896Sfenner} 12956896Sfenner 13056896Sfennervoid 13117680SpstCcpSendResetReq(struct fsm * fp) 13217680Spst{ 13317680Spst Pred1Init(1); /* Initialize Input part */ 13417680Spst LogPrintf(LogCCP, "CcpSendResetReq\n"); 13517680Spst FsmOutput(fp, CODE_RESETREQ, fp->reqid, NULL, 0); 13617680Spst} 13717680Spst 13817680Spststatic void 13917680SpstCcpSendTerminateReq(struct fsm * fp) 14017680Spst{ 14117680Spst /* XXX: No code yet */ 14217680Spst} 14317680Spst 14417680Spststatic void 14517680SpstCcpSendTerminateAck(struct fsm * fp) 14617680Spst{ 14717680Spst LogPrintf(LogCCP, "CcpSendTerminateAck\n"); 14817680Spst FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0); 14917680Spst} 15017680Spst 15117680Spstvoid 15217680SpstCcpRecvResetReq(struct fsm * fp) 15317680Spst{ 15417680Spst Pred1Init(2); /* Initialize Output part */ 15517680Spst} 15617680Spst 15717680Spststatic void 15817680SpstCcpLayerStart(struct fsm * fp) 15917680Spst{ 16017680Spst LogPrintf(LogCCP, "CcpLayerStart.\n"); 16117680Spst} 16217680Spst 16317680Spststatic void 16417680SpstCcpLayerFinish(struct fsm * fp) 16517680Spst{ 16617680Spst LogPrintf(LogCCP, "CcpLayerFinish.\n"); 16717680Spst} 16817680Spst 16917680Spststatic void 17017680SpstCcpLayerDown(struct fsm * fp) 17117680Spst{ 17217680Spst LogPrintf(LogCCP, "CcpLayerDown.\n"); 17317680Spst} 17417680Spst 17517680Spst/* 17617680Spst * Called when CCP has reached to OPEN state 17717680Spst */ 17817680Spststatic void 17917680SpstCcpLayerUp(struct fsm * fp) 18017680Spst{ 18117680Spst LogPrintf(LogCCP, "CcpLayerUp(%d).\n", fp->state); 18217680Spst LogPrintf(LogCCP, "myproto = %d, hisproto = %d\n", 18317680Spst CcpInfo.want_proto, CcpInfo.his_proto); 18417680Spst Pred1Init(3); /* Initialize Input and Output */ 18517680Spst} 18617680Spst 18717680Spstvoid 18817680SpstCcpUp() 18917680Spst{ 19017680Spst FsmUp(&CcpFsm); 19117680Spst LogPrintf(LogCCP, "CCP Up event!!\n"); 19217680Spst} 19317680Spst 19417680Spstvoid 19517680SpstCcpOpen() 19617680Spst{ 19717680Spst if (Enabled(ConfPred1)) 19817680Spst FsmOpen(&CcpFsm); 19917680Spst} 20017680Spst 20117680Spststatic void 20217680SpstCcpDecodeConfig(u_char * cp, int plen, int mode) 20317680Spst{ 20417680Spst int type, length; 20517680Spst char tbuff[100]; 20617680Spst 20717680Spst ackp = AckBuff; 20817680Spst nakp = NakBuff; 20917680Spst rejp = RejBuff; 21017680Spst 21117680Spst while (plen >= sizeof(struct fsmconfig)) { 21217680Spst if (plen < 0) 21317680Spst break; 21417680Spst type = *cp; 21517680Spst length = cp[1]; 21617680Spst if (type <= TY_BSD) 21717680Spst snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes[type], length); 21817680Spst else 21917680Spst snprintf(tbuff, sizeof(tbuff), " "); 22017680Spst 22117680Spst LogPrintf(LogCCP, "%s\n", tbuff); 22217680Spst 22317680Spst switch (type) { 22417680Spst case TY_PRED1: 22517680Spst switch (mode) { 22617680Spst case MODE_REQ: 22717680Spst if (Acceptable(ConfPred1)) { 22817680Spst bcopy(cp, ackp, length); 22917680Spst ackp += length; 23017680Spst CcpInfo.his_proto = type; 23117680Spst } else { 23217680Spst bcopy(cp, rejp, length); 23317680Spst rejp += length; 23417680Spst } 23517680Spst break; 23617680Spst case MODE_NAK: 23717680Spst case MODE_REJ: 23817680Spst CcpInfo.his_reject |= (1 << type); 23917680Spst CcpInfo.want_proto = 0; 24017680Spst break; 24117680Spst } 24217680Spst break; 24317680Spst case TY_BSD: 24417680Spst default: 24517680Spst CcpInfo.my_reject |= (1 << type); 24617680Spst bcopy(cp, rejp, length); 24717680Spst rejp += length; 24817680Spst break; 24956896Sfenner } 25056896Sfenner plen -= length; 25156896Sfenner cp += length; 25256896Sfenner } 25356896Sfenner} 25456896Sfenner 25556896Sfennervoid 25656896SfennerCcpInput(struct mbuf * bp) 25739300Sfenner{ 25839300Sfenner if (phase == PHASE_NETWORK) 25939300Sfenner FsmInput(&CcpFsm, bp); 26039300Sfenner else { 26139300Sfenner LogPrintf(LogERROR, "Unexpected CCP in phase %d\n", phase); 26239300Sfenner pfree(bp); 26339300Sfenner } 26439300Sfenner} 26539300Sfenner