ccp.c revision 25630
11854Swollman/* 222993Speter * PPP Compression Control Protocol (CCP) Module 31573Srgrimes * 41573Srgrimes * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 52049Scsgr * 68870Srgrimes * Copyright (C) 1994, Internet Initiative Japan, Inc. All rights reserverd. 72049Scsgr * 81573Srgrimes * Redistribution and use in source and binary forms are permitted 91854Swollman * provided that the above copyright notice and this paragraph are 101573Srgrimes * duplicated in all such forms and that any documentation, 111573Srgrimes * advertising materials, and other materials related to such 121573Srgrimes * 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.10 1997/02/22 16:10:03 peter 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 "vars.h" 31#include "pred.h" 32#include "cdefs.h" 33 34struct ccpstate CcpInfo; 35 36static void CcpSendConfigReq __P((struct fsm *)); 37static void CcpSendTerminateReq __P((struct fsm *fp)); 38static void CcpSendTerminateAck __P((struct fsm *fp)); 39static void CcpDecodeConfig __P((u_char *cp, int flen, int mode)); 40static void CcpLayerStart __P((struct fsm *)); 41static void CcpLayerFinish __P((struct fsm *)); 42static void CcpLayerUp __P((struct fsm *)); 43static void CcpLayerDown __P((struct fsm *)); 44static void CcpInitRestartCounter __P((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 56 0, 57 { 0, 0, 0, NULL, NULL, NULL }, 58 59 CcpLayerUp, 60 CcpLayerDown, 61 CcpLayerStart, 62 CcpLayerFinish, 63 CcpInitRestartCounter, 64 CcpSendConfigReq, 65 CcpSendTerminateReq, 66 CcpSendTerminateAck, 67 CcpDecodeConfig, 68}; 69 70static char const *cftypes[] = { 71/* 0 */ "OUI", "PRED1", "PRED2", "PUDDLE", 72/* 4 */ "???", "???", "???", "???", 73/* 8 */ "???", "???", "???", "???", 74/* 12 */ "???", "???", "???", "???", 75/* 16 */ "HWPPC", "STAC", "MSPPC", "GAND", 76/* 20 */ "V42BIS", "BSD", 77}; 78 79int 80ReportCcpStatus() 81{ 82 struct ccpstate *icp = &CcpInfo; 83 struct fsm *fp = &CcpFsm; 84 85 printf("%s [%s]\n", fp->name, StateNames[fp->state]); 86 printf("myproto = %s, hisproto = %s\n", 87 cftypes[icp->want_proto], cftypes[icp->his_proto]); 88 printf("Input: %ld --> %ld, Output: %ld --> %ld\n", 89 icp->orgin, icp->compin, icp->orgout, icp->compout); 90 return 0; 91} 92 93void 94CcpInit() 95{ 96 struct ccpstate *icp = &CcpInfo; 97 98 FsmInit(&CcpFsm); 99 bzero(icp, sizeof(struct ccpstate)); 100 if (Enabled(ConfPred1)) 101 icp->want_proto = TY_PRED1; 102 CcpFsm.maxconfig = 10; 103} 104 105static void 106CcpInitRestartCounter(fp) 107struct fsm *fp; 108{ 109 fp->FsmTimer.load = VarRetryTimeout * SECTICKS; 110 fp->restart = 5; 111} 112 113static void 114CcpSendConfigReq(fp) 115struct fsm *fp; 116{ 117 u_char *cp; 118 struct ccpstate *icp = &CcpInfo; 119 120 cp = ReqBuff; 121 LogPrintf(LOG_LCP_BIT, "%s: SendConfigReq\n", fp->name); 122 if (icp->want_proto && !REJECTED(icp, TY_PRED1)) { 123 *cp++ = TY_PRED1; *cp++ = 2; 124 } 125 FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff); 126} 127 128void 129CcpSendResetReq(fp) 130struct fsm *fp; 131{ 132 Pred1Init(1); /* Initialize Input part */ 133 LogPrintf(LOG_LCP_BIT, "%s: SendResetReq\n", fp->name); 134 FsmOutput(fp, CODE_RESETREQ, fp->reqid, NULL, 0); 135} 136 137static void 138CcpSendTerminateReq(fp) 139struct fsm *fp; 140{ 141 /* XXX: No code yet */ 142} 143 144static void 145CcpSendTerminateAck(fp) 146struct fsm *fp; 147{ 148 LogPrintf(LOG_LCP_BIT, " %s: SendTerminateAck\n", fp->name); 149 FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0); 150} 151 152void 153CcpRecvResetReq(fp) 154struct fsm *fp; 155{ 156 Pred1Init(2); /* Initialize Output part */ 157} 158 159static void 160CcpLayerStart(fp) 161struct fsm *fp; 162{ 163 LogPrintf(LOG_LCP_BIT, "%s: LayerStart.\n", fp->name); 164} 165 166static void 167CcpLayerFinish(fp) 168struct fsm *fp; 169{ 170 LogPrintf(LOG_LCP_BIT, "%s: LayerFinish.\n", fp->name); 171} 172 173static void 174CcpLayerDown(fp) 175struct fsm *fp; 176{ 177 LogPrintf(LOG_LCP_BIT, "%s: LayerDown.\n", fp->name); 178} 179 180/* 181 * Called when CCP has reached to OPEN state 182 */ 183static void 184CcpLayerUp(fp) 185struct fsm *fp; 186{ 187#ifdef VERBOSE 188 fprintf(stderr, "%s: LayerUp(%d).\r\n", fp->name, fp->state); 189#endif 190 LogPrintf(LOG_LCP_BIT, "%s: LayerUp.\n", fp->name); 191 LogPrintf(LOG_LCP_BIT, "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(LOG_LCP_BIT, "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(LOG_LCP_BIT, "%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("ccp in phase %d\n", phase); 274 pfree(bp); 275 } 276} 277