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