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 * 20af57ed9fSAtsushi Murai * $Id:$ 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" 31af57ed9fSAtsushi Murai 32af57ed9fSAtsushi Murai extern void PutConfValue(); 33af57ed9fSAtsushi Murai 34af57ed9fSAtsushi Murai struct ccpstate CcpInfo; 35af57ed9fSAtsushi Murai 36af57ed9fSAtsushi Murai static void CcpSendConfigReq(struct fsm *); 37af57ed9fSAtsushi Murai static void CcpSendTerminateReq(struct fsm *fp); 38af57ed9fSAtsushi Murai static void CcpSendTerminateAck(struct fsm *fp); 39af57ed9fSAtsushi Murai static void CcpDecodeConfig(struct mbuf *bp, int mode); 40af57ed9fSAtsushi Murai static void CcpLayerStart(struct fsm *); 41af57ed9fSAtsushi Murai static void CcpLayerFinish(struct fsm *); 42af57ed9fSAtsushi Murai static void CcpLayerUp(struct fsm *); 43af57ed9fSAtsushi Murai static void CcpLayerDown(struct fsm *); 44af57ed9fSAtsushi Murai 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 70af57ed9fSAtsushi Murai static char *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 79af57ed9fSAtsushi Murai void 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]); 88af57ed9fSAtsushi Murai printf("Input: %d --> %d, Output: %d --> %d\n", 89af57ed9fSAtsushi Murai icp->orgin, icp->compin, icp->orgout, icp->compout); 90af57ed9fSAtsushi Murai } 91af57ed9fSAtsushi Murai 92af57ed9fSAtsushi Murai void 93af57ed9fSAtsushi Murai CcpInit() 94af57ed9fSAtsushi Murai { 95af57ed9fSAtsushi Murai struct ccpstate *icp = &CcpInfo; 96af57ed9fSAtsushi Murai 97af57ed9fSAtsushi Murai FsmInit(&CcpFsm); 98af57ed9fSAtsushi Murai bzero(icp, sizeof(struct ccpstate)); 99af57ed9fSAtsushi Murai if (Enabled(ConfPred1)) 100af57ed9fSAtsushi Murai icp->want_proto = TY_PRED1; 101af57ed9fSAtsushi Murai CcpFsm.maxconfig = 10; 102af57ed9fSAtsushi Murai } 103af57ed9fSAtsushi Murai 104af57ed9fSAtsushi Murai static void 105af57ed9fSAtsushi Murai CcpInitRestartCounter(fp) 106af57ed9fSAtsushi Murai struct fsm *fp; 107af57ed9fSAtsushi Murai { 108af57ed9fSAtsushi Murai fp->FsmTimer.load = 3 * SECTICKS; 109af57ed9fSAtsushi Murai fp->restart = 5; 110af57ed9fSAtsushi Murai } 111af57ed9fSAtsushi Murai 112af57ed9fSAtsushi Murai static void 113af57ed9fSAtsushi Murai CcpSendConfigReq(fp) 114af57ed9fSAtsushi Murai struct fsm *fp; 115af57ed9fSAtsushi Murai { 116af57ed9fSAtsushi Murai u_char *cp; 117af57ed9fSAtsushi Murai struct ccpstate *icp = &CcpInfo; 118af57ed9fSAtsushi Murai 119af57ed9fSAtsushi Murai cp = ReqBuff; 120af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "%s: SendConfigReq\n", fp->name); 121af57ed9fSAtsushi Murai if (icp->want_proto && !REJECTED(icp, TY_PRED1)) { 122af57ed9fSAtsushi Murai *cp++ = TY_PRED1; *cp++ = 2; 123af57ed9fSAtsushi Murai } 124af57ed9fSAtsushi Murai FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff); 125af57ed9fSAtsushi Murai } 126af57ed9fSAtsushi Murai 127af57ed9fSAtsushi Murai void 128af57ed9fSAtsushi Murai CcpSendResetReq(fp) 129af57ed9fSAtsushi Murai struct fsm *fp; 130af57ed9fSAtsushi Murai { 131af57ed9fSAtsushi Murai Pred1Init(1); /* Initialize Input part */ 132af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "%s: SendResetReq\n", fp->name); 133af57ed9fSAtsushi Murai FsmOutput(fp, CODE_RESETREQ, fp->reqid, NULL, 0); 134af57ed9fSAtsushi Murai } 135af57ed9fSAtsushi Murai 136af57ed9fSAtsushi Murai static void 137af57ed9fSAtsushi Murai CcpSendTerminateReq(fp) 138af57ed9fSAtsushi Murai struct fsm *fp; 139af57ed9fSAtsushi Murai { 140af57ed9fSAtsushi Murai /* XXX: No code yet */ 141af57ed9fSAtsushi Murai } 142af57ed9fSAtsushi Murai 143af57ed9fSAtsushi Murai static void 144af57ed9fSAtsushi Murai CcpSendTerminateAck(fp) 145af57ed9fSAtsushi Murai struct fsm *fp; 146af57ed9fSAtsushi Murai { 147af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, " %s: SendTerminateAck\n", fp->name); 148af57ed9fSAtsushi Murai FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0); 149af57ed9fSAtsushi Murai } 150af57ed9fSAtsushi Murai 151af57ed9fSAtsushi Murai void 152af57ed9fSAtsushi Murai CcpRecvResetReq(fp) 153af57ed9fSAtsushi Murai struct fsm *fp; 154af57ed9fSAtsushi Murai { 155af57ed9fSAtsushi Murai Pred1Init(2); /* Initialize Output part */ 156af57ed9fSAtsushi Murai } 157af57ed9fSAtsushi Murai 158af57ed9fSAtsushi Murai static void 159af57ed9fSAtsushi Murai CcpLayerStart(fp) 160af57ed9fSAtsushi Murai struct fsm *fp; 161af57ed9fSAtsushi Murai { 162af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "%s: LayerStart.\n", fp->name); 163af57ed9fSAtsushi Murai } 164af57ed9fSAtsushi Murai 165af57ed9fSAtsushi Murai static void 166af57ed9fSAtsushi Murai CcpLayerFinish(fp) 167af57ed9fSAtsushi Murai struct fsm *fp; 168af57ed9fSAtsushi Murai { 169af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "%s: LayerFinish.\n", fp->name); 170af57ed9fSAtsushi Murai } 171af57ed9fSAtsushi Murai 172af57ed9fSAtsushi Murai static void 173af57ed9fSAtsushi Murai CcpLayerDown(fp) 174af57ed9fSAtsushi Murai struct fsm *fp; 175af57ed9fSAtsushi Murai { 176af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "%s: LayerDown.\n", fp->name); 177af57ed9fSAtsushi Murai } 178af57ed9fSAtsushi Murai 179af57ed9fSAtsushi Murai /* 180af57ed9fSAtsushi Murai * Called when CCP has reached to OPEN state 181af57ed9fSAtsushi Murai */ 182af57ed9fSAtsushi Murai static void 183af57ed9fSAtsushi Murai CcpLayerUp(fp) 184af57ed9fSAtsushi Murai struct fsm *fp; 185af57ed9fSAtsushi Murai { 186af57ed9fSAtsushi Murai #ifdef VERBOSE 187af57ed9fSAtsushi Murai fprintf(stderr, "%s: LayerUp(%d).\r\n", fp->name, fp->state); 188af57ed9fSAtsushi Murai #endif 189af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "%s: LayerUp.\n", fp->name); 190af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "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); 199af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "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 210af57ed9fSAtsushi Murai CcpDecodeConfig(bp, mode) 211af57ed9fSAtsushi Murai struct mbuf *bp; 212af57ed9fSAtsushi Murai int mode; 213af57ed9fSAtsushi Murai { 214af57ed9fSAtsushi Murai u_char *cp; 215af57ed9fSAtsushi Murai int plen, type, length; 216af57ed9fSAtsushi Murai u_long *lp, compproto; 217af57ed9fSAtsushi Murai struct compreq *pcomp; 218af57ed9fSAtsushi Murai struct in_addr ipaddr, dstipaddr; 219af57ed9fSAtsushi Murai char tbuff[100]; 220af57ed9fSAtsushi Murai 221af57ed9fSAtsushi Murai plen = plength(bp); 222af57ed9fSAtsushi Murai 223af57ed9fSAtsushi Murai cp = MBUF_CTOP(bp); 224af57ed9fSAtsushi Murai ackp = AckBuff; 225af57ed9fSAtsushi Murai nakp = NakBuff; 226af57ed9fSAtsushi Murai rejp = RejBuff; 227af57ed9fSAtsushi Murai 228af57ed9fSAtsushi Murai while (plen >= sizeof(struct fsmconfig)) { 229af57ed9fSAtsushi Murai if (plen < 0) 230af57ed9fSAtsushi Murai break; 231af57ed9fSAtsushi Murai type = *cp; 232af57ed9fSAtsushi Murai length = cp[1]; 233af57ed9fSAtsushi Murai if (type <= TY_BSD) 234af57ed9fSAtsushi Murai sprintf(tbuff, " %s[%d] ", cftypes[type], length); 235af57ed9fSAtsushi Murai else 236af57ed9fSAtsushi Murai sprintf(tbuff, " "); 237af57ed9fSAtsushi Murai 238af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "%s\n", tbuff); 239af57ed9fSAtsushi Murai 240af57ed9fSAtsushi Murai switch (type) { 241af57ed9fSAtsushi Murai case TY_PRED1: 242af57ed9fSAtsushi Murai switch (mode) { 243af57ed9fSAtsushi Murai case MODE_REQ: 244af57ed9fSAtsushi Murai if (Acceptable(ConfPred1)) { 245af57ed9fSAtsushi Murai bcopy(cp, ackp, length); 246af57ed9fSAtsushi Murai ackp += length; 247af57ed9fSAtsushi Murai CcpInfo.his_proto = type; 248af57ed9fSAtsushi Murai } else { 249af57ed9fSAtsushi Murai bcopy(cp, rejp, length); 250af57ed9fSAtsushi Murai rejp += length; 251af57ed9fSAtsushi Murai } 252af57ed9fSAtsushi Murai break; 253af57ed9fSAtsushi Murai case MODE_NAK: 254af57ed9fSAtsushi Murai case MODE_REJ: 255af57ed9fSAtsushi Murai CcpInfo.his_reject |= (1 << type); 256af57ed9fSAtsushi Murai CcpInfo.want_proto = 0; 257af57ed9fSAtsushi Murai break; 258af57ed9fSAtsushi Murai } 259af57ed9fSAtsushi Murai break; 260af57ed9fSAtsushi Murai case TY_BSD: 261af57ed9fSAtsushi Murai default: 262af57ed9fSAtsushi Murai CcpInfo.my_reject |= (1 << type); 263af57ed9fSAtsushi Murai bcopy(cp, rejp, length); 264af57ed9fSAtsushi Murai rejp += length; 265af57ed9fSAtsushi Murai break; 266af57ed9fSAtsushi Murai } 267af57ed9fSAtsushi Murai plen -= length; 268af57ed9fSAtsushi Murai cp += length; 269af57ed9fSAtsushi Murai } 270af57ed9fSAtsushi Murai } 271af57ed9fSAtsushi Murai 272af57ed9fSAtsushi Murai void 273af57ed9fSAtsushi Murai CcpInput(struct mbuf *bp) 274af57ed9fSAtsushi Murai { 275af57ed9fSAtsushi Murai if (phase == PHASE_NETWORK) 276af57ed9fSAtsushi Murai FsmInput(&CcpFsm, bp); 277af57ed9fSAtsushi Murai else { 278af57ed9fSAtsushi Murai logprintf("ccp in phase %d\n", phase); 279af57ed9fSAtsushi Murai pfree(bp); 280af57ed9fSAtsushi Murai } 281af57ed9fSAtsushi Murai } 282