xref: /freebsd/usr.sbin/ppp/ccp.c (revision 5ebc7e6281887681c3a348a5a4c902e262ccd656)
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