ccp.c revision 26142
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.11 1997/05/10 01:22:06 brian 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 "loadalias.h"
31#include "vars.h"
32#include "pred.h"
33#include "cdefs.h"
34
35struct ccpstate CcpInfo;
36
37static void CcpSendConfigReq __P((struct fsm *));
38static void CcpSendTerminateReq __P((struct fsm *fp));
39static void CcpSendTerminateAck __P((struct fsm *fp));
40static void CcpDecodeConfig __P((u_char *cp, int flen, int mode));
41static void CcpLayerStart __P((struct fsm *));
42static void CcpLayerFinish __P((struct fsm *));
43static void CcpLayerUp __P((struct fsm *));
44static void CcpLayerDown __P((struct fsm *));
45static void CcpInitRestartCounter __P((struct fsm *));
46
47#define	REJECTED(p, x)	(p->his_reject & (1<<x))
48
49struct 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
71static char const *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
80int
81ReportCcpStatus()
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: %ld --> %ld,  Output: %ld --> %ld\n",
90	icp->orgin, icp->compin, icp->orgout, icp->compout);
91  return 0;
92}
93
94void
95CcpInit()
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
106static void
107CcpInitRestartCounter(fp)
108struct fsm *fp;
109{
110  fp->FsmTimer.load = VarRetryTimeout * SECTICKS;
111  fp->restart = 5;
112}
113
114static void
115CcpSendConfigReq(fp)
116struct 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
129void
130CcpSendResetReq(fp)
131struct 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
138static void
139CcpSendTerminateReq(fp)
140struct fsm *fp;
141{
142  /* XXX: No code yet */
143}
144
145static void
146CcpSendTerminateAck(fp)
147struct fsm *fp;
148{
149  LogPrintf(LOG_LCP_BIT, "  %s: SendTerminateAck\n", fp->name);
150  FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0);
151}
152
153void
154CcpRecvResetReq(fp)
155struct fsm *fp;
156{
157  Pred1Init(2);		/* Initialize Output part */
158}
159
160static void
161CcpLayerStart(fp)
162struct fsm *fp;
163{
164  LogPrintf(LOG_LCP_BIT, "%s: LayerStart.\n", fp->name);
165}
166
167static void
168CcpLayerFinish(fp)
169struct fsm *fp;
170{
171  LogPrintf(LOG_LCP_BIT, "%s: LayerFinish.\n", fp->name);
172}
173
174static void
175CcpLayerDown(fp)
176struct 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 */
184static void
185CcpLayerUp(fp)
186struct 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
197void
198CcpUp()
199{
200  FsmUp(&CcpFsm);
201  LogPrintf(LOG_LCP_BIT, "CCP Up event!!\n");
202}
203
204void
205CcpOpen()
206{
207  if (Enabled(ConfPred1))
208    FsmOpen(&CcpFsm);
209}
210
211static void
212CcpDecodeConfig(cp, plen, mode)
213u_char *cp;
214int plen;
215int 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
268void
269CcpInput(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