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$ 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 34 extern void PutConfValue __P((void)); 35 36 struct ccpstate CcpInfo; 37 38 static void CcpSendConfigReq __P((struct fsm *)); 39 static void CcpSendTerminateReq __P((struct fsm *fp)); 40 static void CcpSendTerminateAck __P((struct fsm *fp)); 41 static void CcpDecodeConfig __P((u_char *cp, int flen, int mode)); 42 static void CcpLayerStart __P((struct fsm *)); 43 static void CcpLayerFinish __P((struct fsm *)); 44 static void CcpLayerUp __P((struct fsm *)); 45 static void CcpLayerDown __P((struct fsm *)); 46 static void CcpInitRestartCounter __P((struct fsm *)); 47 48 #define REJECTED(p, x) (p->his_reject & (1<<x)) 49 50 struct fsm CcpFsm = { 51 "CCP", 52 PROTO_CCP, 53 CCP_MAXCODE, 54 OPEN_ACTIVE, 55 ST_INITIAL, 56 0, 0, 0, 57 58 0, 59 { 0, 0, 0, NULL, NULL, NULL }, 60 61 CcpLayerUp, 62 CcpLayerDown, 63 CcpLayerStart, 64 CcpLayerFinish, 65 CcpInitRestartCounter, 66 CcpSendConfigReq, 67 CcpSendTerminateReq, 68 CcpSendTerminateAck, 69 CcpDecodeConfig, 70 }; 71 72 static char const *cftypes[] = { 73 /* 0 */ "OUI", "PRED1", "PRED2", "PUDDLE", 74 /* 4 */ "???", "???", "???", "???", 75 /* 8 */ "???", "???", "???", "???", 76 /* 12 */ "???", "???", "???", "???", 77 /* 16 */ "HWPPC", "STAC", "MSPPC", "GAND", 78 /* 20 */ "V42BIS", "BSD", 79 }; 80 81 void 82 ReportCcpStatus() 83 { 84 struct ccpstate *icp = &CcpInfo; 85 struct fsm *fp = &CcpFsm; 86 87 printf("%s [%s]\n", fp->name, StateNames[fp->state]); 88 printf("myproto = %s, hisproto = %s\n", 89 cftypes[icp->want_proto], cftypes[icp->his_proto]); 90 printf("Input: %ld --> %ld, Output: %ld --> %ld\n", 91 icp->orgin, icp->compin, icp->orgout, icp->compout); 92 } 93 94 void 95 CcpInit() 96 { 97 struct ccpstate *icp = &CcpInfo; 98 99 FsmInit(&CcpFsm); 100 bzero(icp, sizeof(struct ccpstate)); 101 if (Enabled(ConfPred1)) 102 icp->want_proto = TY_PRED1; 103 CcpFsm.maxconfig = 10; 104 } 105 106 static void 107 CcpInitRestartCounter(fp) 108 struct fsm *fp; 109 { 110 fp->FsmTimer.load = VarRetryTimeout * SECTICKS; 111 fp->restart = 5; 112 } 113 114 static void 115 CcpSendConfigReq(fp) 116 struct fsm *fp; 117 { 118 u_char *cp; 119 struct ccpstate *icp = &CcpInfo; 120 121 cp = ReqBuff; 122 LogPrintf(LOG_LCP_BIT, "%s: SendConfigReq\n", fp->name); 123 if (icp->want_proto && !REJECTED(icp, TY_PRED1)) { 124 *cp++ = TY_PRED1; *cp++ = 2; 125 } 126 FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff); 127 } 128 129 void 130 CcpSendResetReq(fp) 131 struct fsm *fp; 132 { 133 Pred1Init(1); /* Initialize Input part */ 134 LogPrintf(LOG_LCP_BIT, "%s: SendResetReq\n", fp->name); 135 FsmOutput(fp, CODE_RESETREQ, fp->reqid, NULL, 0); 136 } 137 138 static void 139 CcpSendTerminateReq(fp) 140 struct fsm *fp; 141 { 142 /* XXX: No code yet */ 143 } 144 145 static void 146 CcpSendTerminateAck(fp) 147 struct fsm *fp; 148 { 149 LogPrintf(LOG_LCP_BIT, " %s: SendTerminateAck\n", fp->name); 150 FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0); 151 } 152 153 void 154 CcpRecvResetReq(fp) 155 struct fsm *fp; 156 { 157 Pred1Init(2); /* Initialize Output part */ 158 } 159 160 static void 161 CcpLayerStart(fp) 162 struct fsm *fp; 163 { 164 LogPrintf(LOG_LCP_BIT, "%s: LayerStart.\n", fp->name); 165 } 166 167 static void 168 CcpLayerFinish(fp) 169 struct fsm *fp; 170 { 171 LogPrintf(LOG_LCP_BIT, "%s: LayerFinish.\n", fp->name); 172 } 173 174 static void 175 CcpLayerDown(fp) 176 struct fsm *fp; 177 { 178 LogPrintf(LOG_LCP_BIT, "%s: LayerDown.\n", fp->name); 179 } 180 181 /* 182 * Called when CCP has reached to OPEN state 183 */ 184 static void 185 CcpLayerUp(fp) 186 struct fsm *fp; 187 { 188 #ifdef VERBOSE 189 fprintf(stderr, "%s: LayerUp(%d).\r\n", fp->name, fp->state); 190 #endif 191 LogPrintf(LOG_LCP_BIT, "%s: LayerUp.\n", fp->name); 192 LogPrintf(LOG_LCP_BIT, "myproto = %d, hisproto = %d\n", 193 CcpInfo.want_proto, CcpInfo.his_proto); 194 Pred1Init(3); /* Initialize Input and Output */ 195 } 196 197 void 198 CcpUp() 199 { 200 FsmUp(&CcpFsm); 201 LogPrintf(LOG_LCP_BIT, "CCP Up event!!\n"); 202 } 203 204 void 205 CcpOpen() 206 { 207 if (Enabled(ConfPred1)) 208 FsmOpen(&CcpFsm); 209 } 210 211 static void 212 CcpDecodeConfig(cp, plen, mode) 213 u_char *cp; 214 int plen; 215 int mode; 216 { 217 int type, length; 218 char tbuff[100]; 219 220 ackp = AckBuff; 221 nakp = NakBuff; 222 rejp = RejBuff; 223 224 while (plen >= sizeof(struct fsmconfig)) { 225 if (plen < 0) 226 break; 227 type = *cp; 228 length = cp[1]; 229 if (type <= TY_BSD) 230 snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes[type], length); 231 else 232 snprintf(tbuff, sizeof(tbuff), " "); 233 234 LogPrintf(LOG_LCP_BIT, "%s\n", tbuff); 235 236 switch (type) { 237 case TY_PRED1: 238 switch (mode) { 239 case MODE_REQ: 240 if (Acceptable(ConfPred1)) { 241 bcopy(cp, ackp, length); 242 ackp += length; 243 CcpInfo.his_proto = type; 244 } else { 245 bcopy(cp, rejp, length); 246 rejp += length; 247 } 248 break; 249 case MODE_NAK: 250 case MODE_REJ: 251 CcpInfo.his_reject |= (1 << type); 252 CcpInfo.want_proto = 0; 253 break; 254 } 255 break; 256 case TY_BSD: 257 default: 258 CcpInfo.my_reject |= (1 << type); 259 bcopy(cp, rejp, length); 260 rejp += length; 261 break; 262 } 263 plen -= length; 264 cp += length; 265 } 266 } 267 268 void 269 CcpInput(struct mbuf *bp) 270 { 271 if (phase == PHASE_NETWORK) 272 FsmInput(&CcpFsm, bp); 273 else { 274 logprintf("ccp in phase %d\n", phase); 275 pfree(bp); 276 } 277 } 278