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