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