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 * 20274e766cSBrian Somers * $Id: ccp.c,v 1.10 1997/02/22 16:10:03 peter 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" 30af57ed9fSAtsushi Murai #include "vars.h" 31ed6a16c1SPoul-Henning Kamp #include "pred.h" 3253c9f6c0SAtsushi Murai #include "cdefs.h" 33af57ed9fSAtsushi Murai 34af57ed9fSAtsushi Murai struct ccpstate CcpInfo; 35af57ed9fSAtsushi Murai 3653c9f6c0SAtsushi Murai static void CcpSendConfigReq __P((struct fsm *)); 3753c9f6c0SAtsushi Murai static void CcpSendTerminateReq __P((struct fsm *fp)); 3853c9f6c0SAtsushi Murai static void CcpSendTerminateAck __P((struct fsm *fp)); 3953c9f6c0SAtsushi Murai static void CcpDecodeConfig __P((u_char *cp, int flen, int mode)); 4053c9f6c0SAtsushi Murai static void CcpLayerStart __P((struct fsm *)); 4153c9f6c0SAtsushi Murai static void CcpLayerFinish __P((struct fsm *)); 4253c9f6c0SAtsushi Murai static void CcpLayerUp __P((struct fsm *)); 4353c9f6c0SAtsushi Murai static void CcpLayerDown __P((struct fsm *)); 4453c9f6c0SAtsushi Murai static void CcpInitRestartCounter __P((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 85af57ed9fSAtsushi Murai printf("%s [%s]\n", fp->name, StateNames[fp->state]); 86af57ed9fSAtsushi Murai printf("myproto = %s, hisproto = %s\n", 87af57ed9fSAtsushi Murai cftypes[icp->want_proto], cftypes[icp->his_proto]); 887b64106aSPoul-Henning Kamp printf("Input: %ld --> %ld, Output: %ld --> %ld\n", 89af57ed9fSAtsushi Murai icp->orgin, icp->compin, icp->orgout, icp->compout); 90274e766cSBrian Somers return 0; 91af57ed9fSAtsushi Murai } 92af57ed9fSAtsushi Murai 93af57ed9fSAtsushi Murai void 94af57ed9fSAtsushi Murai CcpInit() 95af57ed9fSAtsushi Murai { 96af57ed9fSAtsushi Murai struct ccpstate *icp = &CcpInfo; 97af57ed9fSAtsushi Murai 98af57ed9fSAtsushi Murai FsmInit(&CcpFsm); 99af57ed9fSAtsushi Murai bzero(icp, sizeof(struct ccpstate)); 100af57ed9fSAtsushi Murai if (Enabled(ConfPred1)) 101af57ed9fSAtsushi Murai icp->want_proto = TY_PRED1; 102af57ed9fSAtsushi Murai CcpFsm.maxconfig = 10; 103af57ed9fSAtsushi Murai } 104af57ed9fSAtsushi Murai 105af57ed9fSAtsushi Murai static void 106af57ed9fSAtsushi Murai CcpInitRestartCounter(fp) 107af57ed9fSAtsushi Murai struct fsm *fp; 108af57ed9fSAtsushi Murai { 10953c9f6c0SAtsushi Murai fp->FsmTimer.load = VarRetryTimeout * SECTICKS; 110af57ed9fSAtsushi Murai fp->restart = 5; 111af57ed9fSAtsushi Murai } 112af57ed9fSAtsushi Murai 113af57ed9fSAtsushi Murai static void 114af57ed9fSAtsushi Murai CcpSendConfigReq(fp) 115af57ed9fSAtsushi Murai struct fsm *fp; 116af57ed9fSAtsushi Murai { 117af57ed9fSAtsushi Murai u_char *cp; 118af57ed9fSAtsushi Murai struct ccpstate *icp = &CcpInfo; 119af57ed9fSAtsushi Murai 120af57ed9fSAtsushi Murai cp = ReqBuff; 1219c749ffbSPoul-Henning Kamp LogPrintf(LOG_LCP_BIT, "%s: SendConfigReq\n", fp->name); 122af57ed9fSAtsushi Murai if (icp->want_proto && !REJECTED(icp, TY_PRED1)) { 123af57ed9fSAtsushi Murai *cp++ = TY_PRED1; *cp++ = 2; 124af57ed9fSAtsushi Murai } 125af57ed9fSAtsushi Murai FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff); 126af57ed9fSAtsushi Murai } 127af57ed9fSAtsushi Murai 128af57ed9fSAtsushi Murai void 129af57ed9fSAtsushi Murai CcpSendResetReq(fp) 130af57ed9fSAtsushi Murai struct fsm *fp; 131af57ed9fSAtsushi Murai { 132af57ed9fSAtsushi Murai Pred1Init(1); /* Initialize Input part */ 1339c749ffbSPoul-Henning Kamp LogPrintf(LOG_LCP_BIT, "%s: SendResetReq\n", fp->name); 134af57ed9fSAtsushi Murai FsmOutput(fp, CODE_RESETREQ, fp->reqid, NULL, 0); 135af57ed9fSAtsushi Murai } 136af57ed9fSAtsushi Murai 137af57ed9fSAtsushi Murai static void 138af57ed9fSAtsushi Murai CcpSendTerminateReq(fp) 139af57ed9fSAtsushi Murai struct fsm *fp; 140af57ed9fSAtsushi Murai { 141af57ed9fSAtsushi Murai /* XXX: No code yet */ 142af57ed9fSAtsushi Murai } 143af57ed9fSAtsushi Murai 144af57ed9fSAtsushi Murai static void 145af57ed9fSAtsushi Murai CcpSendTerminateAck(fp) 146af57ed9fSAtsushi Murai struct fsm *fp; 147af57ed9fSAtsushi Murai { 1489c749ffbSPoul-Henning Kamp LogPrintf(LOG_LCP_BIT, " %s: SendTerminateAck\n", fp->name); 149af57ed9fSAtsushi Murai FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0); 150af57ed9fSAtsushi Murai } 151af57ed9fSAtsushi Murai 152af57ed9fSAtsushi Murai void 153af57ed9fSAtsushi Murai CcpRecvResetReq(fp) 154af57ed9fSAtsushi Murai struct fsm *fp; 155af57ed9fSAtsushi Murai { 156af57ed9fSAtsushi Murai Pred1Init(2); /* Initialize Output part */ 157af57ed9fSAtsushi Murai } 158af57ed9fSAtsushi Murai 159af57ed9fSAtsushi Murai static void 160af57ed9fSAtsushi Murai CcpLayerStart(fp) 161af57ed9fSAtsushi Murai struct fsm *fp; 162af57ed9fSAtsushi Murai { 1639c749ffbSPoul-Henning Kamp LogPrintf(LOG_LCP_BIT, "%s: LayerStart.\n", fp->name); 164af57ed9fSAtsushi Murai } 165af57ed9fSAtsushi Murai 166af57ed9fSAtsushi Murai static void 167af57ed9fSAtsushi Murai CcpLayerFinish(fp) 168af57ed9fSAtsushi Murai struct fsm *fp; 169af57ed9fSAtsushi Murai { 1709c749ffbSPoul-Henning Kamp LogPrintf(LOG_LCP_BIT, "%s: LayerFinish.\n", fp->name); 171af57ed9fSAtsushi Murai } 172af57ed9fSAtsushi Murai 173af57ed9fSAtsushi Murai static void 174af57ed9fSAtsushi Murai CcpLayerDown(fp) 175af57ed9fSAtsushi Murai struct fsm *fp; 176af57ed9fSAtsushi Murai { 1779c749ffbSPoul-Henning Kamp LogPrintf(LOG_LCP_BIT, "%s: LayerDown.\n", fp->name); 178af57ed9fSAtsushi Murai } 179af57ed9fSAtsushi Murai 180af57ed9fSAtsushi Murai /* 181af57ed9fSAtsushi Murai * Called when CCP has reached to OPEN state 182af57ed9fSAtsushi Murai */ 183af57ed9fSAtsushi Murai static void 184af57ed9fSAtsushi Murai CcpLayerUp(fp) 185af57ed9fSAtsushi Murai struct fsm *fp; 186af57ed9fSAtsushi Murai { 187af57ed9fSAtsushi Murai #ifdef VERBOSE 188af57ed9fSAtsushi Murai fprintf(stderr, "%s: LayerUp(%d).\r\n", fp->name, fp->state); 189af57ed9fSAtsushi Murai #endif 1909c749ffbSPoul-Henning Kamp LogPrintf(LOG_LCP_BIT, "%s: LayerUp.\n", fp->name); 1919c749ffbSPoul-Henning Kamp LogPrintf(LOG_LCP_BIT, "myproto = %d, hisproto = %d\n", 192af57ed9fSAtsushi Murai CcpInfo.want_proto, CcpInfo.his_proto); 193af57ed9fSAtsushi Murai Pred1Init(3); /* Initialize Input and Output */ 194af57ed9fSAtsushi Murai } 195af57ed9fSAtsushi Murai 196af57ed9fSAtsushi Murai void 197af57ed9fSAtsushi Murai CcpUp() 198af57ed9fSAtsushi Murai { 199af57ed9fSAtsushi Murai FsmUp(&CcpFsm); 2009c749ffbSPoul-Henning Kamp LogPrintf(LOG_LCP_BIT, "CCP Up event!!\n"); 201af57ed9fSAtsushi Murai } 202af57ed9fSAtsushi Murai 203af57ed9fSAtsushi Murai void 204af57ed9fSAtsushi Murai CcpOpen() 205af57ed9fSAtsushi Murai { 206af57ed9fSAtsushi Murai if (Enabled(ConfPred1)) 207af57ed9fSAtsushi Murai FsmOpen(&CcpFsm); 208af57ed9fSAtsushi Murai } 209af57ed9fSAtsushi Murai 210af57ed9fSAtsushi Murai static void 21153c9f6c0SAtsushi Murai CcpDecodeConfig(cp, plen, mode) 21253c9f6c0SAtsushi Murai u_char *cp; 21353c9f6c0SAtsushi Murai int plen; 214af57ed9fSAtsushi Murai int mode; 215af57ed9fSAtsushi Murai { 21653c9f6c0SAtsushi Murai int type, length; 217af57ed9fSAtsushi Murai char tbuff[100]; 218af57ed9fSAtsushi Murai 219af57ed9fSAtsushi Murai ackp = AckBuff; 220af57ed9fSAtsushi Murai nakp = NakBuff; 221af57ed9fSAtsushi Murai rejp = RejBuff; 222af57ed9fSAtsushi Murai 223af57ed9fSAtsushi Murai while (plen >= sizeof(struct fsmconfig)) { 224af57ed9fSAtsushi Murai if (plen < 0) 225af57ed9fSAtsushi Murai break; 226af57ed9fSAtsushi Murai type = *cp; 227af57ed9fSAtsushi Murai length = cp[1]; 228af57ed9fSAtsushi Murai if (type <= TY_BSD) 22999c02d39SWarner Losh snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes[type], length); 230af57ed9fSAtsushi Murai else 23199c02d39SWarner Losh snprintf(tbuff, sizeof(tbuff), " "); 232af57ed9fSAtsushi Murai 2339c749ffbSPoul-Henning Kamp LogPrintf(LOG_LCP_BIT, "%s\n", tbuff); 234af57ed9fSAtsushi Murai 235af57ed9fSAtsushi Murai switch (type) { 236af57ed9fSAtsushi Murai case TY_PRED1: 237af57ed9fSAtsushi Murai switch (mode) { 238af57ed9fSAtsushi Murai case MODE_REQ: 239af57ed9fSAtsushi Murai if (Acceptable(ConfPred1)) { 240af57ed9fSAtsushi Murai bcopy(cp, ackp, length); 241af57ed9fSAtsushi Murai ackp += length; 242af57ed9fSAtsushi Murai CcpInfo.his_proto = type; 243af57ed9fSAtsushi Murai } else { 244af57ed9fSAtsushi Murai bcopy(cp, rejp, length); 245af57ed9fSAtsushi Murai rejp += length; 246af57ed9fSAtsushi Murai } 247af57ed9fSAtsushi Murai break; 248af57ed9fSAtsushi Murai case MODE_NAK: 249af57ed9fSAtsushi Murai case MODE_REJ: 250af57ed9fSAtsushi Murai CcpInfo.his_reject |= (1 << type); 251af57ed9fSAtsushi Murai CcpInfo.want_proto = 0; 252af57ed9fSAtsushi Murai break; 253af57ed9fSAtsushi Murai } 254af57ed9fSAtsushi Murai break; 255af57ed9fSAtsushi Murai case TY_BSD: 256af57ed9fSAtsushi Murai default: 257af57ed9fSAtsushi Murai CcpInfo.my_reject |= (1 << type); 258af57ed9fSAtsushi Murai bcopy(cp, rejp, length); 259af57ed9fSAtsushi Murai rejp += length; 260af57ed9fSAtsushi Murai break; 261af57ed9fSAtsushi Murai } 262af57ed9fSAtsushi Murai plen -= length; 263af57ed9fSAtsushi Murai cp += length; 264af57ed9fSAtsushi Murai } 265af57ed9fSAtsushi Murai } 266af57ed9fSAtsushi Murai 267af57ed9fSAtsushi Murai void 268af57ed9fSAtsushi Murai CcpInput(struct mbuf *bp) 269af57ed9fSAtsushi Murai { 270af57ed9fSAtsushi Murai if (phase == PHASE_NETWORK) 271af57ed9fSAtsushi Murai FsmInput(&CcpFsm, bp); 272af57ed9fSAtsushi Murai else { 273af57ed9fSAtsushi Murai logprintf("ccp in phase %d\n", phase); 274af57ed9fSAtsushi Murai pfree(bp); 275af57ed9fSAtsushi Murai } 276af57ed9fSAtsushi Murai } 277