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