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