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