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 * 209780ef31SBrian Somers * $Id: ccp.c,v 1.17 1997/10/26 01:02:10 brian Exp $ 21af57ed9fSAtsushi Murai * 22af57ed9fSAtsushi Murai * TODO: 23af57ed9fSAtsushi Murai * o Support other compression protocols 24af57ed9fSAtsushi Murai */ 2575240ed1SBrian Somers #include <sys/param.h> 2675240ed1SBrian Somers #include <netinet/in.h> 2775240ed1SBrian Somers 2875240ed1SBrian Somers #include <stdio.h> 2975240ed1SBrian Somers #include <string.h> 3075240ed1SBrian Somers 3175240ed1SBrian Somers #include "mbuf.h" 3275240ed1SBrian Somers #include "log.h" 3375240ed1SBrian Somers #include "defs.h" 3475240ed1SBrian Somers #include "timer.h" 35af57ed9fSAtsushi Murai #include "fsm.h" 36af57ed9fSAtsushi Murai #include "lcpproto.h" 37af57ed9fSAtsushi Murai #include "lcp.h" 38af57ed9fSAtsushi Murai #include "ccp.h" 39af57ed9fSAtsushi Murai #include "phase.h" 406ed9fb2fSBrian Somers #include "loadalias.h" 4175240ed1SBrian Somers #include "command.h" 42af57ed9fSAtsushi Murai #include "vars.h" 43ed6a16c1SPoul-Henning Kamp #include "pred.h" 44af57ed9fSAtsushi Murai 45af57ed9fSAtsushi Murai struct ccpstate CcpInfo; 46af57ed9fSAtsushi Murai 47927145beSBrian Somers static void CcpSendConfigReq(struct fsm *); 4875240ed1SBrian Somers static void CcpSendTerminateReq(struct fsm *); 4975240ed1SBrian Somers static void CcpSendTerminateAck(struct fsm *); 5075240ed1SBrian Somers static void CcpDecodeConfig(u_char *, int, int); 51927145beSBrian Somers static void CcpLayerStart(struct fsm *); 52927145beSBrian Somers static void CcpLayerFinish(struct fsm *); 53927145beSBrian Somers static void CcpLayerUp(struct fsm *); 54927145beSBrian Somers static void CcpLayerDown(struct fsm *); 55927145beSBrian Somers static void CcpInitRestartCounter(struct fsm *); 56af57ed9fSAtsushi Murai 57af57ed9fSAtsushi Murai #define REJECTED(p, x) (p->his_reject & (1<<x)) 58af57ed9fSAtsushi Murai 59af57ed9fSAtsushi Murai struct fsm CcpFsm = { 60af57ed9fSAtsushi Murai "CCP", 61af57ed9fSAtsushi Murai PROTO_CCP, 62af57ed9fSAtsushi Murai CCP_MAXCODE, 63af57ed9fSAtsushi Murai OPEN_ACTIVE, 64af57ed9fSAtsushi Murai ST_INITIAL, 65af57ed9fSAtsushi Murai 0, 0, 0, 66af57ed9fSAtsushi Murai 0, 67af57ed9fSAtsushi Murai {0, 0, 0, NULL, NULL, NULL}, 68cb611434SBrian Somers {0, 0, 0, NULL, NULL, NULL}, 69cb611434SBrian Somers LogCCP, 70af57ed9fSAtsushi Murai 71af57ed9fSAtsushi Murai CcpLayerUp, 72af57ed9fSAtsushi Murai CcpLayerDown, 73af57ed9fSAtsushi Murai CcpLayerStart, 74af57ed9fSAtsushi Murai CcpLayerFinish, 75af57ed9fSAtsushi Murai CcpInitRestartCounter, 76af57ed9fSAtsushi Murai CcpSendConfigReq, 77af57ed9fSAtsushi Murai CcpSendTerminateReq, 78af57ed9fSAtsushi Murai CcpSendTerminateAck, 79af57ed9fSAtsushi Murai CcpDecodeConfig, 80af57ed9fSAtsushi Murai }; 81af57ed9fSAtsushi Murai 82e53374eaSPoul-Henning Kamp static char const *cftypes[] = { 83af57ed9fSAtsushi Murai /* 0 */ "OUI", "PRED1", "PRED2", "PUDDLE", 84af57ed9fSAtsushi Murai /* 4 */ "???", "???", "???", "???", 85af57ed9fSAtsushi Murai /* 8 */ "???", "???", "???", "???", 86af57ed9fSAtsushi Murai /* 12 */ "???", "???", "???", "???", 87af57ed9fSAtsushi Murai /* 16 */ "HWPPC", "STAC", "MSPPC", "GAND", 88af57ed9fSAtsushi Murai /* 20 */ "V42BIS", "BSD", 89af57ed9fSAtsushi Murai }; 90af57ed9fSAtsushi Murai 91274e766cSBrian Somers int 92af57ed9fSAtsushi Murai ReportCcpStatus() 93af57ed9fSAtsushi Murai { 94af57ed9fSAtsushi Murai struct ccpstate *icp = &CcpInfo; 95af57ed9fSAtsushi Murai struct fsm *fp = &CcpFsm; 96af57ed9fSAtsushi Murai 97927145beSBrian Somers if (VarTerm) { 98927145beSBrian Somers fprintf(VarTerm, "%s [%s]\n", fp->name, StateNames[fp->state]); 99927145beSBrian Somers fprintf(VarTerm, "myproto = %s, hisproto = %s\n", 100af57ed9fSAtsushi Murai cftypes[icp->want_proto], cftypes[icp->his_proto]); 101927145beSBrian Somers fprintf(VarTerm, "Input: %ld --> %ld, Output: %ld --> %ld\n", 102af57ed9fSAtsushi Murai icp->orgin, icp->compin, icp->orgout, icp->compout); 103927145beSBrian Somers } 104274e766cSBrian Somers return 0; 105af57ed9fSAtsushi Murai } 106af57ed9fSAtsushi Murai 107af57ed9fSAtsushi Murai void 108af57ed9fSAtsushi Murai CcpInit() 109af57ed9fSAtsushi Murai { 110af57ed9fSAtsushi Murai struct ccpstate *icp = &CcpInfo; 111af57ed9fSAtsushi Murai 112af57ed9fSAtsushi Murai FsmInit(&CcpFsm); 11375240ed1SBrian Somers memset(icp, '\0', sizeof(struct ccpstate)); 114af57ed9fSAtsushi Murai if (Enabled(ConfPred1)) 115af57ed9fSAtsushi Murai icp->want_proto = TY_PRED1; 116af57ed9fSAtsushi Murai CcpFsm.maxconfig = 10; 117af57ed9fSAtsushi Murai } 118af57ed9fSAtsushi Murai 119af57ed9fSAtsushi Murai static void 120944f7098SBrian Somers CcpInitRestartCounter(struct fsm *fp) 121af57ed9fSAtsushi Murai { 12253c9f6c0SAtsushi Murai fp->FsmTimer.load = VarRetryTimeout * SECTICKS; 123af57ed9fSAtsushi Murai fp->restart = 5; 124af57ed9fSAtsushi Murai } 125af57ed9fSAtsushi Murai 126af57ed9fSAtsushi Murai static void 127944f7098SBrian Somers CcpSendConfigReq(struct fsm *fp) 128af57ed9fSAtsushi Murai { 129af57ed9fSAtsushi Murai u_char *cp; 130af57ed9fSAtsushi Murai struct ccpstate *icp = &CcpInfo; 131af57ed9fSAtsushi Murai 132af57ed9fSAtsushi Murai cp = ReqBuff; 133cb611434SBrian Somers LogPrintf(LogCCP, "CcpSendConfigReq\n"); 134af57ed9fSAtsushi Murai if (icp->want_proto && !REJECTED(icp, TY_PRED1)) { 135944f7098SBrian Somers *cp++ = TY_PRED1; 136944f7098SBrian Somers *cp++ = 2; 137af57ed9fSAtsushi Murai } 138af57ed9fSAtsushi Murai FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff); 139af57ed9fSAtsushi Murai } 140af57ed9fSAtsushi Murai 141af57ed9fSAtsushi Murai void 142944f7098SBrian Somers CcpSendResetReq(struct fsm *fp) 143af57ed9fSAtsushi Murai { 144cb611434SBrian Somers LogPrintf(LogCCP, "CcpSendResetReq\n"); 145af57ed9fSAtsushi Murai FsmOutput(fp, CODE_RESETREQ, fp->reqid, NULL, 0); 146af57ed9fSAtsushi Murai } 147af57ed9fSAtsushi Murai 148af57ed9fSAtsushi Murai static void 149944f7098SBrian Somers CcpSendTerminateReq(struct fsm *fp) 150af57ed9fSAtsushi Murai { 151af57ed9fSAtsushi Murai /* XXX: No code yet */ 152af57ed9fSAtsushi Murai } 153af57ed9fSAtsushi Murai 154af57ed9fSAtsushi Murai static void 155944f7098SBrian Somers CcpSendTerminateAck(struct fsm *fp) 156af57ed9fSAtsushi Murai { 157cb611434SBrian Somers LogPrintf(LogCCP, "CcpSendTerminateAck\n"); 158af57ed9fSAtsushi Murai FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0); 159af57ed9fSAtsushi Murai } 160af57ed9fSAtsushi Murai 161af57ed9fSAtsushi Murai void 162944f7098SBrian Somers CcpRecvResetReq(struct fsm *fp) 163af57ed9fSAtsushi Murai { 164af57ed9fSAtsushi Murai Pred1Init(2); /* Initialize Output part */ 165af57ed9fSAtsushi Murai } 166af57ed9fSAtsushi Murai 167af57ed9fSAtsushi Murai static void 168944f7098SBrian Somers CcpLayerStart(struct fsm *fp) 169af57ed9fSAtsushi Murai { 170cb611434SBrian Somers LogPrintf(LogCCP, "CcpLayerStart.\n"); 171af57ed9fSAtsushi Murai } 172af57ed9fSAtsushi Murai 173af57ed9fSAtsushi Murai static void 174944f7098SBrian Somers CcpLayerFinish(struct fsm *fp) 175af57ed9fSAtsushi Murai { 176cb611434SBrian Somers LogPrintf(LogCCP, "CcpLayerFinish.\n"); 177af57ed9fSAtsushi Murai } 178af57ed9fSAtsushi Murai 179af57ed9fSAtsushi Murai static void 180944f7098SBrian Somers CcpLayerDown(struct fsm *fp) 181af57ed9fSAtsushi Murai { 182cb611434SBrian Somers LogPrintf(LogCCP, "CcpLayerDown.\n"); 183af57ed9fSAtsushi Murai } 184af57ed9fSAtsushi Murai 185af57ed9fSAtsushi Murai /* 186af57ed9fSAtsushi Murai * Called when CCP has reached to OPEN state 187af57ed9fSAtsushi Murai */ 188af57ed9fSAtsushi Murai static void 189944f7098SBrian Somers CcpLayerUp(struct fsm *fp) 190af57ed9fSAtsushi Murai { 191cb611434SBrian Somers LogPrintf(LogCCP, "CcpLayerUp(%d).\n", fp->state); 192cb611434SBrian Somers LogPrintf(LogCCP, "myproto = %d, hisproto = %d\n", 193af57ed9fSAtsushi Murai CcpInfo.want_proto, CcpInfo.his_proto); 194af57ed9fSAtsushi Murai Pred1Init(3); /* Initialize Input and Output */ 195af57ed9fSAtsushi Murai } 196af57ed9fSAtsushi Murai 197af57ed9fSAtsushi Murai void 198af57ed9fSAtsushi Murai CcpUp() 199af57ed9fSAtsushi Murai { 200af57ed9fSAtsushi Murai FsmUp(&CcpFsm); 201cb611434SBrian Somers LogPrintf(LogCCP, "CCP Up event!!\n"); 202af57ed9fSAtsushi Murai } 203af57ed9fSAtsushi Murai 204af57ed9fSAtsushi Murai void 205af57ed9fSAtsushi Murai CcpOpen() 206af57ed9fSAtsushi Murai { 207af57ed9fSAtsushi Murai if (Enabled(ConfPred1)) 208af57ed9fSAtsushi Murai FsmOpen(&CcpFsm); 209af57ed9fSAtsushi Murai } 210af57ed9fSAtsushi Murai 211af57ed9fSAtsushi Murai static void 2129780ef31SBrian Somers CcpDecodeConfig(u_char *cp, int plen, int mode_type) 213af57ed9fSAtsushi Murai { 21453c9f6c0SAtsushi Murai int type, length; 215af57ed9fSAtsushi Murai char tbuff[100]; 216af57ed9fSAtsushi Murai 217af57ed9fSAtsushi Murai ackp = AckBuff; 218af57ed9fSAtsushi Murai nakp = NakBuff; 219af57ed9fSAtsushi Murai rejp = RejBuff; 220af57ed9fSAtsushi Murai 221af57ed9fSAtsushi Murai while (plen >= sizeof(struct fsmconfig)) { 222af57ed9fSAtsushi Murai if (plen < 0) 223af57ed9fSAtsushi Murai break; 224af57ed9fSAtsushi Murai type = *cp; 225af57ed9fSAtsushi Murai length = cp[1]; 226af57ed9fSAtsushi Murai if (type <= TY_BSD) 22799c02d39SWarner Losh snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes[type], length); 228af57ed9fSAtsushi Murai else 22999c02d39SWarner Losh snprintf(tbuff, sizeof(tbuff), " "); 230af57ed9fSAtsushi Murai 231cb611434SBrian Somers LogPrintf(LogCCP, "%s\n", tbuff); 232af57ed9fSAtsushi Murai 233af57ed9fSAtsushi Murai switch (type) { 234af57ed9fSAtsushi Murai case TY_PRED1: 2359780ef31SBrian Somers switch (mode_type) { 236af57ed9fSAtsushi Murai case MODE_REQ: 237af57ed9fSAtsushi Murai if (Acceptable(ConfPred1)) { 23875240ed1SBrian Somers memcpy(ackp, cp, length); 239af57ed9fSAtsushi Murai ackp += length; 240af57ed9fSAtsushi Murai CcpInfo.his_proto = type; 241af57ed9fSAtsushi Murai } else { 24275240ed1SBrian Somers memcpy(rejp, cp, length); 243af57ed9fSAtsushi Murai rejp += length; 244af57ed9fSAtsushi Murai } 245af57ed9fSAtsushi Murai break; 246af57ed9fSAtsushi Murai case MODE_NAK: 247af57ed9fSAtsushi Murai case MODE_REJ: 248af57ed9fSAtsushi Murai CcpInfo.his_reject |= (1 << type); 249af57ed9fSAtsushi Murai CcpInfo.want_proto = 0; 250af57ed9fSAtsushi Murai break; 251af57ed9fSAtsushi Murai } 252af57ed9fSAtsushi Murai break; 253af57ed9fSAtsushi Murai case TY_BSD: 254af57ed9fSAtsushi Murai default: 255af57ed9fSAtsushi Murai CcpInfo.my_reject |= (1 << type); 25675240ed1SBrian Somers memcpy(rejp, cp, length); 257af57ed9fSAtsushi Murai rejp += length; 258af57ed9fSAtsushi Murai break; 259af57ed9fSAtsushi Murai } 260af57ed9fSAtsushi Murai plen -= length; 261af57ed9fSAtsushi Murai cp += length; 262af57ed9fSAtsushi Murai } 263af57ed9fSAtsushi Murai } 264af57ed9fSAtsushi Murai 265af57ed9fSAtsushi Murai void 266af57ed9fSAtsushi Murai CcpInput(struct mbuf *bp) 267af57ed9fSAtsushi Murai { 268af57ed9fSAtsushi Murai if (phase == PHASE_NETWORK) 269af57ed9fSAtsushi Murai FsmInput(&CcpFsm, bp); 270af57ed9fSAtsushi Murai else { 27129a6597cSBrian Somers if (phase > PHASE_NETWORK) 272927145beSBrian Somers LogPrintf(LogERROR, "Unexpected CCP in phase %d\n", phase); 273af57ed9fSAtsushi Murai pfree(bp); 274af57ed9fSAtsushi Murai } 275af57ed9fSAtsushi Murai } 276