xref: /freebsd/usr.sbin/ppp/ccp.c (revision 927145be97d8d5b69a0a1a86dc7e9d637102c7d0)
1af57ed9fSAtsushi Murai /*
2af57ed9fSAtsushi Murai  *	   PPP Compression Control Protocol (CCP) Module
3af57ed9fSAtsushi Murai  *
4af57ed9fSAtsushi Murai  *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
5af57ed9fSAtsushi Murai  *
6af57ed9fSAtsushi Murai  *   Copyright (C) 1994, Internet Initiative Japan, Inc. All rights reserverd.
7af57ed9fSAtsushi Murai  *
8af57ed9fSAtsushi Murai  * Redistribution and use in source and binary forms are permitted
9af57ed9fSAtsushi Murai  * provided that the above copyright notice and this paragraph are
10af57ed9fSAtsushi Murai  * duplicated in all such forms and that any documentation,
11af57ed9fSAtsushi Murai  * advertising materials, and other materials related to such
12af57ed9fSAtsushi Murai  * distribution and use acknowledge that the software was developed
13af57ed9fSAtsushi Murai  * by the Internet Initiative Japan, Inc.  The name of the
14af57ed9fSAtsushi Murai  * IIJ may not be used to endorse or promote products derived
15af57ed9fSAtsushi Murai  * from this software without specific prior written permission.
16af57ed9fSAtsushi Murai  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17af57ed9fSAtsushi Murai  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18af57ed9fSAtsushi Murai  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19af57ed9fSAtsushi Murai  *
20927145beSBrian Somers  * $Id: ccp.c,v 1.12 1997/05/26 00:43:56 brian Exp $
21af57ed9fSAtsushi Murai  *
22af57ed9fSAtsushi Murai  *	TODO:
23af57ed9fSAtsushi Murai  *		o Support other compression protocols
24af57ed9fSAtsushi Murai  */
25af57ed9fSAtsushi Murai #include "fsm.h"
26af57ed9fSAtsushi Murai #include "lcpproto.h"
27af57ed9fSAtsushi Murai #include "lcp.h"
28af57ed9fSAtsushi Murai #include "ccp.h"
29af57ed9fSAtsushi Murai #include "phase.h"
306ed9fb2fSBrian Somers #include "loadalias.h"
31af57ed9fSAtsushi Murai #include "vars.h"
32ed6a16c1SPoul-Henning Kamp #include "pred.h"
33af57ed9fSAtsushi Murai 
34af57ed9fSAtsushi Murai struct ccpstate CcpInfo;
35af57ed9fSAtsushi Murai 
36927145beSBrian Somers static void CcpSendConfigReq(struct fsm *);
37927145beSBrian Somers static void CcpSendTerminateReq(struct fsm *fp);
38927145beSBrian Somers static void CcpSendTerminateAck(struct fsm *fp);
39927145beSBrian Somers static void CcpDecodeConfig(u_char *cp, int flen, int mode);
40927145beSBrian Somers static void CcpLayerStart(struct fsm *);
41927145beSBrian Somers static void CcpLayerFinish(struct fsm *);
42927145beSBrian Somers static void CcpLayerUp(struct fsm *);
43927145beSBrian Somers static void CcpLayerDown(struct fsm *);
44927145beSBrian Somers static void CcpInitRestartCounter(struct fsm *);
45af57ed9fSAtsushi Murai 
46af57ed9fSAtsushi Murai #define	REJECTED(p, x)	(p->his_reject & (1<<x))
47af57ed9fSAtsushi Murai 
48af57ed9fSAtsushi Murai struct fsm CcpFsm = {
49af57ed9fSAtsushi Murai   "CCP",
50af57ed9fSAtsushi Murai   PROTO_CCP,
51af57ed9fSAtsushi Murai   CCP_MAXCODE,
52af57ed9fSAtsushi Murai   OPEN_ACTIVE,
53af57ed9fSAtsushi Murai   ST_INITIAL,
54af57ed9fSAtsushi Murai   0, 0, 0,
55af57ed9fSAtsushi Murai 
56af57ed9fSAtsushi Murai   0,
57af57ed9fSAtsushi Murai   { 0, 0, 0, NULL, NULL, NULL },
58af57ed9fSAtsushi Murai 
59af57ed9fSAtsushi Murai   CcpLayerUp,
60af57ed9fSAtsushi Murai   CcpLayerDown,
61af57ed9fSAtsushi Murai   CcpLayerStart,
62af57ed9fSAtsushi Murai   CcpLayerFinish,
63af57ed9fSAtsushi Murai   CcpInitRestartCounter,
64af57ed9fSAtsushi Murai   CcpSendConfigReq,
65af57ed9fSAtsushi Murai   CcpSendTerminateReq,
66af57ed9fSAtsushi Murai   CcpSendTerminateAck,
67af57ed9fSAtsushi Murai   CcpDecodeConfig,
68af57ed9fSAtsushi Murai };
69af57ed9fSAtsushi Murai 
70e53374eaSPoul-Henning Kamp static char const *cftypes[] = {
71af57ed9fSAtsushi Murai /*  0 */  "OUI",    "PRED1", "PRED2", "PUDDLE",
72af57ed9fSAtsushi Murai /*  4 */  "???",    "???",   "???",   "???",
73af57ed9fSAtsushi Murai /*  8 */  "???",    "???",   "???",   "???",
74af57ed9fSAtsushi Murai /* 12 */  "???",    "???",   "???",   "???",
75af57ed9fSAtsushi Murai /* 16 */  "HWPPC",  "STAC",  "MSPPC", "GAND",
76af57ed9fSAtsushi Murai /* 20 */  "V42BIS", "BSD",
77af57ed9fSAtsushi Murai };
78af57ed9fSAtsushi Murai 
79274e766cSBrian Somers int
80af57ed9fSAtsushi Murai ReportCcpStatus()
81af57ed9fSAtsushi Murai {
82af57ed9fSAtsushi Murai   struct ccpstate *icp = &CcpInfo;
83af57ed9fSAtsushi Murai   struct fsm *fp = &CcpFsm;
84af57ed9fSAtsushi Murai 
85927145beSBrian Somers   if (VarTerm) {
86927145beSBrian Somers     fprintf(VarTerm, "%s [%s]\n", fp->name, StateNames[fp->state]);
87927145beSBrian Somers     fprintf(VarTerm, "myproto = %s, hisproto = %s\n",
88af57ed9fSAtsushi Murai 	    cftypes[icp->want_proto], cftypes[icp->his_proto]);
89927145beSBrian Somers     fprintf(VarTerm, "Input: %ld --> %ld,  Output: %ld --> %ld\n",
90af57ed9fSAtsushi Murai 	    icp->orgin, icp->compin, icp->orgout, icp->compout);
91927145beSBrian Somers   }
92274e766cSBrian Somers   return 0;
93af57ed9fSAtsushi Murai }
94af57ed9fSAtsushi Murai 
95af57ed9fSAtsushi Murai void
96af57ed9fSAtsushi Murai CcpInit()
97af57ed9fSAtsushi Murai {
98af57ed9fSAtsushi Murai   struct ccpstate *icp = &CcpInfo;
99af57ed9fSAtsushi Murai 
100af57ed9fSAtsushi Murai   FsmInit(&CcpFsm);
101af57ed9fSAtsushi Murai   bzero(icp, sizeof(struct ccpstate));
102af57ed9fSAtsushi Murai   if (Enabled(ConfPred1))
103af57ed9fSAtsushi Murai     icp->want_proto = TY_PRED1;
104af57ed9fSAtsushi Murai   CcpFsm.maxconfig = 10;
105af57ed9fSAtsushi Murai }
106af57ed9fSAtsushi Murai 
107af57ed9fSAtsushi Murai static void
108af57ed9fSAtsushi Murai CcpInitRestartCounter(fp)
109af57ed9fSAtsushi Murai struct fsm *fp;
110af57ed9fSAtsushi Murai {
11153c9f6c0SAtsushi Murai   fp->FsmTimer.load = VarRetryTimeout * SECTICKS;
112af57ed9fSAtsushi Murai   fp->restart = 5;
113af57ed9fSAtsushi Murai }
114af57ed9fSAtsushi Murai 
115af57ed9fSAtsushi Murai static void
116af57ed9fSAtsushi Murai CcpSendConfigReq(fp)
117af57ed9fSAtsushi Murai struct fsm *fp;
118af57ed9fSAtsushi Murai {
119af57ed9fSAtsushi Murai   u_char *cp;
120af57ed9fSAtsushi Murai   struct ccpstate *icp = &CcpInfo;
121af57ed9fSAtsushi Murai 
122af57ed9fSAtsushi Murai   cp = ReqBuff;
123927145beSBrian Somers   LogPrintf(LogLCP, "CcpSendConfigReq\n");
124af57ed9fSAtsushi Murai   if (icp->want_proto && !REJECTED(icp, TY_PRED1)) {
125af57ed9fSAtsushi Murai     *cp++ = TY_PRED1; *cp++ = 2;
126af57ed9fSAtsushi Murai   }
127af57ed9fSAtsushi Murai   FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff);
128af57ed9fSAtsushi Murai }
129af57ed9fSAtsushi Murai 
130af57ed9fSAtsushi Murai void
131af57ed9fSAtsushi Murai CcpSendResetReq(fp)
132af57ed9fSAtsushi Murai struct fsm *fp;
133af57ed9fSAtsushi Murai {
134af57ed9fSAtsushi Murai   Pred1Init(1);		/* Initialize Input part */
135927145beSBrian Somers   LogPrintf(LogLCP, "CcpSendResetReq\n");
136af57ed9fSAtsushi Murai   FsmOutput(fp, CODE_RESETREQ, fp->reqid, NULL, 0);
137af57ed9fSAtsushi Murai }
138af57ed9fSAtsushi Murai 
139af57ed9fSAtsushi Murai static void
140af57ed9fSAtsushi Murai CcpSendTerminateReq(fp)
141af57ed9fSAtsushi Murai struct fsm *fp;
142af57ed9fSAtsushi Murai {
143af57ed9fSAtsushi Murai   /* XXX: No code yet */
144af57ed9fSAtsushi Murai }
145af57ed9fSAtsushi Murai 
146af57ed9fSAtsushi Murai static void
147af57ed9fSAtsushi Murai CcpSendTerminateAck(fp)
148af57ed9fSAtsushi Murai struct fsm *fp;
149af57ed9fSAtsushi Murai {
150927145beSBrian Somers   LogPrintf(LogLCP, "CcpSendTerminateAck\n");
151af57ed9fSAtsushi Murai   FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0);
152af57ed9fSAtsushi Murai }
153af57ed9fSAtsushi Murai 
154af57ed9fSAtsushi Murai void
155af57ed9fSAtsushi Murai CcpRecvResetReq(fp)
156af57ed9fSAtsushi Murai struct fsm *fp;
157af57ed9fSAtsushi Murai {
158af57ed9fSAtsushi Murai   Pred1Init(2);		/* Initialize Output part */
159af57ed9fSAtsushi Murai }
160af57ed9fSAtsushi Murai 
161af57ed9fSAtsushi Murai static void
162af57ed9fSAtsushi Murai CcpLayerStart(fp)
163af57ed9fSAtsushi Murai struct fsm *fp;
164af57ed9fSAtsushi Murai {
165927145beSBrian Somers   LogPrintf(LogLCP, "CcpLayerStart.\n");
166af57ed9fSAtsushi Murai }
167af57ed9fSAtsushi Murai 
168af57ed9fSAtsushi Murai static void
169af57ed9fSAtsushi Murai CcpLayerFinish(fp)
170af57ed9fSAtsushi Murai struct fsm *fp;
171af57ed9fSAtsushi Murai {
172927145beSBrian Somers   LogPrintf(LogLCP, "CcpLayerFinish.\n");
173af57ed9fSAtsushi Murai }
174af57ed9fSAtsushi Murai 
175af57ed9fSAtsushi Murai static void
176af57ed9fSAtsushi Murai CcpLayerDown(fp)
177af57ed9fSAtsushi Murai struct fsm *fp;
178af57ed9fSAtsushi Murai {
179927145beSBrian Somers   LogPrintf(LogLCP, "CcpLayerDown.\n");
180af57ed9fSAtsushi Murai }
181af57ed9fSAtsushi Murai 
182af57ed9fSAtsushi Murai /*
183af57ed9fSAtsushi Murai  *  Called when CCP has reached to OPEN state
184af57ed9fSAtsushi Murai  */
185af57ed9fSAtsushi Murai static void
186af57ed9fSAtsushi Murai CcpLayerUp(fp)
187af57ed9fSAtsushi Murai struct fsm *fp;
188af57ed9fSAtsushi Murai {
189927145beSBrian Somers   LogPrintf(LogLCP, "CcpLayerUp(%d).\n", fp->state);
190927145beSBrian Somers   LogPrintf(LogLCP, "myproto = %d, hisproto = %d\n",
191af57ed9fSAtsushi Murai 	CcpInfo.want_proto, CcpInfo.his_proto);
192af57ed9fSAtsushi Murai   Pred1Init(3);		/* Initialize Input and Output */
193af57ed9fSAtsushi Murai }
194af57ed9fSAtsushi Murai 
195af57ed9fSAtsushi Murai void
196af57ed9fSAtsushi Murai CcpUp()
197af57ed9fSAtsushi Murai {
198af57ed9fSAtsushi Murai   FsmUp(&CcpFsm);
199927145beSBrian Somers   LogPrintf(LogLCP, "CCP Up event!!\n");
200af57ed9fSAtsushi Murai }
201af57ed9fSAtsushi Murai 
202af57ed9fSAtsushi Murai void
203af57ed9fSAtsushi Murai CcpOpen()
204af57ed9fSAtsushi Murai {
205af57ed9fSAtsushi Murai   if (Enabled(ConfPred1))
206af57ed9fSAtsushi Murai     FsmOpen(&CcpFsm);
207af57ed9fSAtsushi Murai }
208af57ed9fSAtsushi Murai 
209af57ed9fSAtsushi Murai static void
21053c9f6c0SAtsushi Murai CcpDecodeConfig(cp, plen, mode)
21153c9f6c0SAtsushi Murai u_char *cp;
21253c9f6c0SAtsushi Murai int plen;
213af57ed9fSAtsushi Murai int mode;
214af57ed9fSAtsushi Murai {
21553c9f6c0SAtsushi Murai   int type, length;
216af57ed9fSAtsushi Murai   char tbuff[100];
217af57ed9fSAtsushi Murai 
218af57ed9fSAtsushi Murai   ackp = AckBuff;
219af57ed9fSAtsushi Murai   nakp = NakBuff;
220af57ed9fSAtsushi Murai   rejp = RejBuff;
221af57ed9fSAtsushi Murai 
222af57ed9fSAtsushi Murai   while (plen >= sizeof(struct fsmconfig)) {
223af57ed9fSAtsushi Murai     if (plen < 0)
224af57ed9fSAtsushi Murai       break;
225af57ed9fSAtsushi Murai     type = *cp;
226af57ed9fSAtsushi Murai     length = cp[1];
227af57ed9fSAtsushi Murai     if (type <= TY_BSD)
22899c02d39SWarner Losh       snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes[type], length);
229af57ed9fSAtsushi Murai     else
23099c02d39SWarner Losh       snprintf(tbuff, sizeof(tbuff), " ");
231af57ed9fSAtsushi Murai 
232927145beSBrian Somers     LogPrintf(LogLCP, "%s\n", tbuff);
233af57ed9fSAtsushi Murai 
234af57ed9fSAtsushi Murai     switch (type) {
235af57ed9fSAtsushi Murai     case TY_PRED1:
236af57ed9fSAtsushi Murai       switch (mode) {
237af57ed9fSAtsushi Murai       case MODE_REQ:
238af57ed9fSAtsushi Murai 	if (Acceptable(ConfPred1)) {
239af57ed9fSAtsushi Murai 	  bcopy(cp, ackp, length);
240af57ed9fSAtsushi Murai 	  ackp += length;
241af57ed9fSAtsushi Murai 	  CcpInfo.his_proto = type;
242af57ed9fSAtsushi Murai 	} else {
243af57ed9fSAtsushi Murai 	  bcopy(cp, rejp, length);
244af57ed9fSAtsushi Murai 	  rejp += length;
245af57ed9fSAtsushi Murai 	}
246af57ed9fSAtsushi Murai 	break;
247af57ed9fSAtsushi Murai       case MODE_NAK:
248af57ed9fSAtsushi Murai       case MODE_REJ:
249af57ed9fSAtsushi Murai 	CcpInfo.his_reject |= (1 << type);
250af57ed9fSAtsushi Murai 	CcpInfo.want_proto = 0;
251af57ed9fSAtsushi Murai 	break;
252af57ed9fSAtsushi Murai       }
253af57ed9fSAtsushi Murai       break;
254af57ed9fSAtsushi Murai     case TY_BSD:
255af57ed9fSAtsushi Murai     default:
256af57ed9fSAtsushi Murai       CcpInfo.my_reject |= (1 << type);
257af57ed9fSAtsushi Murai       bcopy(cp, rejp, length);
258af57ed9fSAtsushi Murai       rejp += length;
259af57ed9fSAtsushi Murai       break;
260af57ed9fSAtsushi Murai     }
261af57ed9fSAtsushi Murai     plen -= length;
262af57ed9fSAtsushi Murai     cp += length;
263af57ed9fSAtsushi Murai   }
264af57ed9fSAtsushi Murai }
265af57ed9fSAtsushi Murai 
266af57ed9fSAtsushi Murai void
267af57ed9fSAtsushi Murai CcpInput(struct mbuf *bp)
268af57ed9fSAtsushi Murai {
269af57ed9fSAtsushi Murai   if (phase == PHASE_NETWORK)
270af57ed9fSAtsushi Murai     FsmInput(&CcpFsm, bp);
271af57ed9fSAtsushi Murai   else {
272927145beSBrian Somers     LogPrintf(LogERROR, "Unexpected CCP in phase %d\n", phase);
273af57ed9fSAtsushi Murai     pfree(bp);
274af57ed9fSAtsushi Murai   }
275af57ed9fSAtsushi Murai }
276