ccp.c revision 6060
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 32extern void PutConfValue(); 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(struct mbuf *bp, 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 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 *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 79void 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: %d --> %d, Output: %d --> %d\n", 89 icp->orgin, icp->compin, icp->orgout, icp->compout); 90} 91 92void 93CcpInit() 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 104static void 105CcpInitRestartCounter(fp) 106struct fsm *fp; 107{ 108 fp->FsmTimer.load = 3 * SECTICKS; 109 fp->restart = 5; 110} 111 112static void 113CcpSendConfigReq(fp) 114struct 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 127void 128CcpSendResetReq(fp) 129struct 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 136static void 137CcpSendTerminateReq(fp) 138struct fsm *fp; 139{ 140 /* XXX: No code yet */ 141} 142 143static void 144CcpSendTerminateAck(fp) 145struct fsm *fp; 146{ 147 LogPrintf(LOG_LCP, " %s: SendTerminateAck\n", fp->name); 148 FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0); 149} 150 151void 152CcpRecvResetReq(fp) 153struct fsm *fp; 154{ 155 Pred1Init(2); /* Initialize Output part */ 156} 157 158static void 159CcpLayerStart(fp) 160struct fsm *fp; 161{ 162 LogPrintf(LOG_LCP, "%s: LayerStart.\n", fp->name); 163} 164 165static void 166CcpLayerFinish(fp) 167struct fsm *fp; 168{ 169 LogPrintf(LOG_LCP, "%s: LayerFinish.\n", fp->name); 170} 171 172static void 173CcpLayerDown(fp) 174struct 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 */ 182static void 183CcpLayerUp(fp) 184struct 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 195void 196CcpUp() 197{ 198 FsmUp(&CcpFsm); 199 LogPrintf(LOG_LCP, "CCP Up event!!\n"); 200} 201 202void 203CcpOpen() 204{ 205 if (Enabled(ConfPred1)) 206 FsmOpen(&CcpFsm); 207} 208 209static void 210CcpDecodeConfig(bp, mode) 211struct mbuf *bp; 212int 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 272void 273CcpInput(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