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