1af57ed9fSAtsushi Murai /* 2af57ed9fSAtsushi Murai * PPP Compression Control Protocol (CCP) Module 3af57ed9fSAtsushi Murai * 4af57ed9fSAtsushi Murai * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5af57ed9fSAtsushi Murai * 6af57ed9fSAtsushi Murai * Copyright (C) 1994, Internet Initiative Japan, Inc. All rights reserverd. 7af57ed9fSAtsushi Murai * 8af57ed9fSAtsushi Murai * Redistribution and use in source and binary forms are permitted 9af57ed9fSAtsushi Murai * provided that the above copyright notice and this paragraph are 10af57ed9fSAtsushi Murai * duplicated in all such forms and that any documentation, 11af57ed9fSAtsushi Murai * advertising materials, and other materials related to such 12af57ed9fSAtsushi Murai * distribution and use acknowledge that the software was developed 13af57ed9fSAtsushi Murai * by the Internet Initiative Japan, Inc. The name of the 14af57ed9fSAtsushi Murai * IIJ may not be used to endorse or promote products derived 15af57ed9fSAtsushi Murai * from this software without specific prior written permission. 16af57ed9fSAtsushi Murai * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17af57ed9fSAtsushi Murai * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18af57ed9fSAtsushi Murai * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19af57ed9fSAtsushi Murai * 20927145beSBrian Somers * $Id: ccp.c,v 1.12 1997/05/26 00:43:56 brian Exp $ 21af57ed9fSAtsushi Murai * 22af57ed9fSAtsushi Murai * TODO: 23af57ed9fSAtsushi Murai * o Support other compression protocols 24af57ed9fSAtsushi Murai */ 25af57ed9fSAtsushi Murai #include "fsm.h" 26af57ed9fSAtsushi Murai #include "lcpproto.h" 27af57ed9fSAtsushi Murai #include "lcp.h" 28af57ed9fSAtsushi Murai #include "ccp.h" 29af57ed9fSAtsushi Murai #include "phase.h" 306ed9fb2fSBrian Somers #include "loadalias.h" 31af57ed9fSAtsushi Murai #include "vars.h" 32ed6a16c1SPoul-Henning Kamp #include "pred.h" 33af57ed9fSAtsushi Murai 34af57ed9fSAtsushi Murai struct ccpstate CcpInfo; 35af57ed9fSAtsushi Murai 36927145beSBrian Somers static void CcpSendConfigReq(struct fsm *); 37927145beSBrian Somers static void CcpSendTerminateReq(struct fsm *fp); 38927145beSBrian Somers static void CcpSendTerminateAck(struct fsm *fp); 39927145beSBrian Somers static void CcpDecodeConfig(u_char *cp, int flen, int mode); 40927145beSBrian Somers static void CcpLayerStart(struct fsm *); 41927145beSBrian Somers static void CcpLayerFinish(struct fsm *); 42927145beSBrian Somers static void CcpLayerUp(struct fsm *); 43927145beSBrian Somers static void CcpLayerDown(struct fsm *); 44927145beSBrian Somers static void CcpInitRestartCounter(struct fsm *); 45af57ed9fSAtsushi Murai 46af57ed9fSAtsushi Murai #define REJECTED(p, x) (p->his_reject & (1<<x)) 47af57ed9fSAtsushi Murai 48af57ed9fSAtsushi Murai struct fsm CcpFsm = { 49af57ed9fSAtsushi Murai "CCP", 50af57ed9fSAtsushi Murai PROTO_CCP, 51af57ed9fSAtsushi Murai CCP_MAXCODE, 52af57ed9fSAtsushi Murai OPEN_ACTIVE, 53af57ed9fSAtsushi Murai ST_INITIAL, 54af57ed9fSAtsushi Murai 0, 0, 0, 55af57ed9fSAtsushi Murai 56af57ed9fSAtsushi Murai 0, 57af57ed9fSAtsushi Murai { 0, 0, 0, NULL, NULL, NULL }, 58af57ed9fSAtsushi Murai 59af57ed9fSAtsushi Murai CcpLayerUp, 60af57ed9fSAtsushi Murai CcpLayerDown, 61af57ed9fSAtsushi Murai CcpLayerStart, 62af57ed9fSAtsushi Murai CcpLayerFinish, 63af57ed9fSAtsushi Murai CcpInitRestartCounter, 64af57ed9fSAtsushi Murai CcpSendConfigReq, 65af57ed9fSAtsushi Murai CcpSendTerminateReq, 66af57ed9fSAtsushi Murai CcpSendTerminateAck, 67af57ed9fSAtsushi Murai CcpDecodeConfig, 68af57ed9fSAtsushi Murai }; 69af57ed9fSAtsushi Murai 70e53374eaSPoul-Henning Kamp static char const *cftypes[] = { 71af57ed9fSAtsushi Murai /* 0 */ "OUI", "PRED1", "PRED2", "PUDDLE", 72af57ed9fSAtsushi Murai /* 4 */ "???", "???", "???", "???", 73af57ed9fSAtsushi Murai /* 8 */ "???", "???", "???", "???", 74af57ed9fSAtsushi Murai /* 12 */ "???", "???", "???", "???", 75af57ed9fSAtsushi Murai /* 16 */ "HWPPC", "STAC", "MSPPC", "GAND", 76af57ed9fSAtsushi Murai /* 20 */ "V42BIS", "BSD", 77af57ed9fSAtsushi Murai }; 78af57ed9fSAtsushi Murai 79274e766cSBrian Somers int 80af57ed9fSAtsushi Murai ReportCcpStatus() 81af57ed9fSAtsushi Murai { 82af57ed9fSAtsushi Murai struct ccpstate *icp = &CcpInfo; 83af57ed9fSAtsushi Murai struct fsm *fp = &CcpFsm; 84af57ed9fSAtsushi Murai 85927145beSBrian Somers if (VarTerm) { 86927145beSBrian Somers fprintf(VarTerm, "%s [%s]\n", fp->name, StateNames[fp->state]); 87927145beSBrian Somers fprintf(VarTerm, "myproto = %s, hisproto = %s\n", 88af57ed9fSAtsushi Murai cftypes[icp->want_proto], cftypes[icp->his_proto]); 89927145beSBrian Somers fprintf(VarTerm, "Input: %ld --> %ld, Output: %ld --> %ld\n", 90af57ed9fSAtsushi Murai icp->orgin, icp->compin, icp->orgout, icp->compout); 91927145beSBrian Somers } 92274e766cSBrian Somers return 0; 93af57ed9fSAtsushi Murai } 94af57ed9fSAtsushi Murai 95af57ed9fSAtsushi Murai void 96af57ed9fSAtsushi Murai CcpInit() 97af57ed9fSAtsushi Murai { 98af57ed9fSAtsushi Murai struct ccpstate *icp = &CcpInfo; 99af57ed9fSAtsushi Murai 100af57ed9fSAtsushi Murai FsmInit(&CcpFsm); 101af57ed9fSAtsushi Murai bzero(icp, sizeof(struct ccpstate)); 102af57ed9fSAtsushi Murai if (Enabled(ConfPred1)) 103af57ed9fSAtsushi Murai icp->want_proto = TY_PRED1; 104af57ed9fSAtsushi Murai CcpFsm.maxconfig = 10; 105af57ed9fSAtsushi Murai } 106af57ed9fSAtsushi Murai 107af57ed9fSAtsushi Murai static void 108af57ed9fSAtsushi Murai CcpInitRestartCounter(fp) 109af57ed9fSAtsushi Murai struct fsm *fp; 110af57ed9fSAtsushi Murai { 11153c9f6c0SAtsushi Murai fp->FsmTimer.load = VarRetryTimeout * SECTICKS; 112af57ed9fSAtsushi Murai fp->restart = 5; 113af57ed9fSAtsushi Murai } 114af57ed9fSAtsushi Murai 115af57ed9fSAtsushi Murai static void 116af57ed9fSAtsushi Murai CcpSendConfigReq(fp) 117af57ed9fSAtsushi Murai struct fsm *fp; 118af57ed9fSAtsushi Murai { 119af57ed9fSAtsushi Murai u_char *cp; 120af57ed9fSAtsushi Murai struct ccpstate *icp = &CcpInfo; 121af57ed9fSAtsushi Murai 122af57ed9fSAtsushi Murai cp = ReqBuff; 123927145beSBrian Somers LogPrintf(LogLCP, "CcpSendConfigReq\n"); 124af57ed9fSAtsushi Murai if (icp->want_proto && !REJECTED(icp, TY_PRED1)) { 125af57ed9fSAtsushi Murai *cp++ = TY_PRED1; *cp++ = 2; 126af57ed9fSAtsushi Murai } 127af57ed9fSAtsushi Murai FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff); 128af57ed9fSAtsushi Murai } 129af57ed9fSAtsushi Murai 130af57ed9fSAtsushi Murai void 131af57ed9fSAtsushi Murai CcpSendResetReq(fp) 132af57ed9fSAtsushi Murai struct fsm *fp; 133af57ed9fSAtsushi Murai { 134af57ed9fSAtsushi Murai Pred1Init(1); /* Initialize Input part */ 135927145beSBrian Somers LogPrintf(LogLCP, "CcpSendResetReq\n"); 136af57ed9fSAtsushi Murai FsmOutput(fp, CODE_RESETREQ, fp->reqid, NULL, 0); 137af57ed9fSAtsushi Murai } 138af57ed9fSAtsushi Murai 139af57ed9fSAtsushi Murai static void 140af57ed9fSAtsushi Murai CcpSendTerminateReq(fp) 141af57ed9fSAtsushi Murai struct fsm *fp; 142af57ed9fSAtsushi Murai { 143af57ed9fSAtsushi Murai /* XXX: No code yet */ 144af57ed9fSAtsushi Murai } 145af57ed9fSAtsushi Murai 146af57ed9fSAtsushi Murai static void 147af57ed9fSAtsushi Murai CcpSendTerminateAck(fp) 148af57ed9fSAtsushi Murai struct fsm *fp; 149af57ed9fSAtsushi Murai { 150927145beSBrian Somers LogPrintf(LogLCP, "CcpSendTerminateAck\n"); 151af57ed9fSAtsushi Murai FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0); 152af57ed9fSAtsushi Murai } 153af57ed9fSAtsushi Murai 154af57ed9fSAtsushi Murai void 155af57ed9fSAtsushi Murai CcpRecvResetReq(fp) 156af57ed9fSAtsushi Murai struct fsm *fp; 157af57ed9fSAtsushi Murai { 158af57ed9fSAtsushi Murai Pred1Init(2); /* Initialize Output part */ 159af57ed9fSAtsushi Murai } 160af57ed9fSAtsushi Murai 161af57ed9fSAtsushi Murai static void 162af57ed9fSAtsushi Murai CcpLayerStart(fp) 163af57ed9fSAtsushi Murai struct fsm *fp; 164af57ed9fSAtsushi Murai { 165927145beSBrian Somers LogPrintf(LogLCP, "CcpLayerStart.\n"); 166af57ed9fSAtsushi Murai } 167af57ed9fSAtsushi Murai 168af57ed9fSAtsushi Murai static void 169af57ed9fSAtsushi Murai CcpLayerFinish(fp) 170af57ed9fSAtsushi Murai struct fsm *fp; 171af57ed9fSAtsushi Murai { 172927145beSBrian Somers LogPrintf(LogLCP, "CcpLayerFinish.\n"); 173af57ed9fSAtsushi Murai } 174af57ed9fSAtsushi Murai 175af57ed9fSAtsushi Murai static void 176af57ed9fSAtsushi Murai CcpLayerDown(fp) 177af57ed9fSAtsushi Murai struct fsm *fp; 178af57ed9fSAtsushi Murai { 179927145beSBrian Somers LogPrintf(LogLCP, "CcpLayerDown.\n"); 180af57ed9fSAtsushi Murai } 181af57ed9fSAtsushi Murai 182af57ed9fSAtsushi Murai /* 183af57ed9fSAtsushi Murai * Called when CCP has reached to OPEN state 184af57ed9fSAtsushi Murai */ 185af57ed9fSAtsushi Murai static void 186af57ed9fSAtsushi Murai CcpLayerUp(fp) 187af57ed9fSAtsushi Murai struct fsm *fp; 188af57ed9fSAtsushi Murai { 189927145beSBrian Somers LogPrintf(LogLCP, "CcpLayerUp(%d).\n", fp->state); 190927145beSBrian Somers LogPrintf(LogLCP, "myproto = %d, hisproto = %d\n", 191af57ed9fSAtsushi Murai CcpInfo.want_proto, CcpInfo.his_proto); 192af57ed9fSAtsushi Murai Pred1Init(3); /* Initialize Input and Output */ 193af57ed9fSAtsushi Murai } 194af57ed9fSAtsushi Murai 195af57ed9fSAtsushi Murai void 196af57ed9fSAtsushi Murai CcpUp() 197af57ed9fSAtsushi Murai { 198af57ed9fSAtsushi Murai FsmUp(&CcpFsm); 199927145beSBrian Somers LogPrintf(LogLCP, "CCP Up event!!\n"); 200af57ed9fSAtsushi Murai } 201af57ed9fSAtsushi Murai 202af57ed9fSAtsushi Murai void 203af57ed9fSAtsushi Murai CcpOpen() 204af57ed9fSAtsushi Murai { 205af57ed9fSAtsushi Murai if (Enabled(ConfPred1)) 206af57ed9fSAtsushi Murai FsmOpen(&CcpFsm); 207af57ed9fSAtsushi Murai } 208af57ed9fSAtsushi Murai 209af57ed9fSAtsushi Murai static void 21053c9f6c0SAtsushi Murai CcpDecodeConfig(cp, plen, mode) 21153c9f6c0SAtsushi Murai u_char *cp; 21253c9f6c0SAtsushi Murai int plen; 213af57ed9fSAtsushi Murai int mode; 214af57ed9fSAtsushi Murai { 21553c9f6c0SAtsushi Murai int type, length; 216af57ed9fSAtsushi Murai char tbuff[100]; 217af57ed9fSAtsushi Murai 218af57ed9fSAtsushi Murai ackp = AckBuff; 219af57ed9fSAtsushi Murai nakp = NakBuff; 220af57ed9fSAtsushi Murai rejp = RejBuff; 221af57ed9fSAtsushi Murai 222af57ed9fSAtsushi Murai while (plen >= sizeof(struct fsmconfig)) { 223af57ed9fSAtsushi Murai if (plen < 0) 224af57ed9fSAtsushi Murai break; 225af57ed9fSAtsushi Murai type = *cp; 226af57ed9fSAtsushi Murai length = cp[1]; 227af57ed9fSAtsushi Murai if (type <= TY_BSD) 22899c02d39SWarner Losh snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes[type], length); 229af57ed9fSAtsushi Murai else 23099c02d39SWarner Losh snprintf(tbuff, sizeof(tbuff), " "); 231af57ed9fSAtsushi Murai 232927145beSBrian Somers LogPrintf(LogLCP, "%s\n", tbuff); 233af57ed9fSAtsushi Murai 234af57ed9fSAtsushi Murai switch (type) { 235af57ed9fSAtsushi Murai case TY_PRED1: 236af57ed9fSAtsushi Murai switch (mode) { 237af57ed9fSAtsushi Murai case MODE_REQ: 238af57ed9fSAtsushi Murai if (Acceptable(ConfPred1)) { 239af57ed9fSAtsushi Murai bcopy(cp, ackp, length); 240af57ed9fSAtsushi Murai ackp += length; 241af57ed9fSAtsushi Murai CcpInfo.his_proto = type; 242af57ed9fSAtsushi Murai } else { 243af57ed9fSAtsushi Murai bcopy(cp, rejp, length); 244af57ed9fSAtsushi Murai rejp += length; 245af57ed9fSAtsushi Murai } 246af57ed9fSAtsushi Murai break; 247af57ed9fSAtsushi Murai case MODE_NAK: 248af57ed9fSAtsushi Murai case MODE_REJ: 249af57ed9fSAtsushi Murai CcpInfo.his_reject |= (1 << type); 250af57ed9fSAtsushi Murai CcpInfo.want_proto = 0; 251af57ed9fSAtsushi Murai break; 252af57ed9fSAtsushi Murai } 253af57ed9fSAtsushi Murai break; 254af57ed9fSAtsushi Murai case TY_BSD: 255af57ed9fSAtsushi Murai default: 256af57ed9fSAtsushi Murai CcpInfo.my_reject |= (1 << type); 257af57ed9fSAtsushi Murai bcopy(cp, rejp, length); 258af57ed9fSAtsushi Murai rejp += length; 259af57ed9fSAtsushi Murai break; 260af57ed9fSAtsushi Murai } 261af57ed9fSAtsushi Murai plen -= length; 262af57ed9fSAtsushi Murai cp += length; 263af57ed9fSAtsushi Murai } 264af57ed9fSAtsushi Murai } 265af57ed9fSAtsushi Murai 266af57ed9fSAtsushi Murai void 267af57ed9fSAtsushi Murai CcpInput(struct mbuf *bp) 268af57ed9fSAtsushi Murai { 269af57ed9fSAtsushi Murai if (phase == PHASE_NETWORK) 270af57ed9fSAtsushi Murai FsmInput(&CcpFsm, bp); 271af57ed9fSAtsushi Murai else { 272927145beSBrian Somers LogPrintf(LogERROR, "Unexpected CCP in phase %d\n", phase); 273af57ed9fSAtsushi Murai pfree(bp); 274af57ed9fSAtsushi Murai } 275af57ed9fSAtsushi Murai } 276