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