xref: /freebsd/usr.sbin/ppp/ccp.c (revision 274e766c998381279af6ead2d711057aa6307df9)
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  *
20274e766cSBrian Somers  * $Id: ccp.c,v 1.10 1997/02/22 16:10:03 peter 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"
30af57ed9fSAtsushi Murai #include "vars.h"
31ed6a16c1SPoul-Henning Kamp #include "pred.h"
3253c9f6c0SAtsushi Murai #include "cdefs.h"
33af57ed9fSAtsushi Murai 
34af57ed9fSAtsushi Murai struct ccpstate CcpInfo;
35af57ed9fSAtsushi Murai 
3653c9f6c0SAtsushi Murai static void CcpSendConfigReq __P((struct fsm *));
3753c9f6c0SAtsushi Murai static void CcpSendTerminateReq __P((struct fsm *fp));
3853c9f6c0SAtsushi Murai static void CcpSendTerminateAck __P((struct fsm *fp));
3953c9f6c0SAtsushi Murai static void CcpDecodeConfig __P((u_char *cp, int flen, int mode));
4053c9f6c0SAtsushi Murai static void CcpLayerStart __P((struct fsm *));
4153c9f6c0SAtsushi Murai static void CcpLayerFinish __P((struct fsm *));
4253c9f6c0SAtsushi Murai static void CcpLayerUp __P((struct fsm *));
4353c9f6c0SAtsushi Murai static void CcpLayerDown __P((struct fsm *));
4453c9f6c0SAtsushi Murai static void CcpInitRestartCounter __P((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 
85af57ed9fSAtsushi Murai   printf("%s [%s]\n", fp->name, StateNames[fp->state]);
86af57ed9fSAtsushi Murai   printf("myproto = %s, hisproto = %s\n",
87af57ed9fSAtsushi Murai 	cftypes[icp->want_proto], cftypes[icp->his_proto]);
887b64106aSPoul-Henning Kamp   printf("Input: %ld --> %ld,  Output: %ld --> %ld\n",
89af57ed9fSAtsushi Murai 	icp->orgin, icp->compin, icp->orgout, icp->compout);
90274e766cSBrian Somers   return 0;
91af57ed9fSAtsushi Murai }
92af57ed9fSAtsushi Murai 
93af57ed9fSAtsushi Murai void
94af57ed9fSAtsushi Murai CcpInit()
95af57ed9fSAtsushi Murai {
96af57ed9fSAtsushi Murai   struct ccpstate *icp = &CcpInfo;
97af57ed9fSAtsushi Murai 
98af57ed9fSAtsushi Murai   FsmInit(&CcpFsm);
99af57ed9fSAtsushi Murai   bzero(icp, sizeof(struct ccpstate));
100af57ed9fSAtsushi Murai   if (Enabled(ConfPred1))
101af57ed9fSAtsushi Murai     icp->want_proto = TY_PRED1;
102af57ed9fSAtsushi Murai   CcpFsm.maxconfig = 10;
103af57ed9fSAtsushi Murai }
104af57ed9fSAtsushi Murai 
105af57ed9fSAtsushi Murai static void
106af57ed9fSAtsushi Murai CcpInitRestartCounter(fp)
107af57ed9fSAtsushi Murai struct fsm *fp;
108af57ed9fSAtsushi Murai {
10953c9f6c0SAtsushi Murai   fp->FsmTimer.load = VarRetryTimeout * SECTICKS;
110af57ed9fSAtsushi Murai   fp->restart = 5;
111af57ed9fSAtsushi Murai }
112af57ed9fSAtsushi Murai 
113af57ed9fSAtsushi Murai static void
114af57ed9fSAtsushi Murai CcpSendConfigReq(fp)
115af57ed9fSAtsushi Murai struct fsm *fp;
116af57ed9fSAtsushi Murai {
117af57ed9fSAtsushi Murai   u_char *cp;
118af57ed9fSAtsushi Murai   struct ccpstate *icp = &CcpInfo;
119af57ed9fSAtsushi Murai 
120af57ed9fSAtsushi Murai   cp = ReqBuff;
1219c749ffbSPoul-Henning Kamp   LogPrintf(LOG_LCP_BIT, "%s: SendConfigReq\n", fp->name);
122af57ed9fSAtsushi Murai   if (icp->want_proto && !REJECTED(icp, TY_PRED1)) {
123af57ed9fSAtsushi Murai     *cp++ = TY_PRED1; *cp++ = 2;
124af57ed9fSAtsushi Murai   }
125af57ed9fSAtsushi Murai   FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff);
126af57ed9fSAtsushi Murai }
127af57ed9fSAtsushi Murai 
128af57ed9fSAtsushi Murai void
129af57ed9fSAtsushi Murai CcpSendResetReq(fp)
130af57ed9fSAtsushi Murai struct fsm *fp;
131af57ed9fSAtsushi Murai {
132af57ed9fSAtsushi Murai   Pred1Init(1);		/* Initialize Input part */
1339c749ffbSPoul-Henning Kamp   LogPrintf(LOG_LCP_BIT, "%s: SendResetReq\n", fp->name);
134af57ed9fSAtsushi Murai   FsmOutput(fp, CODE_RESETREQ, fp->reqid, NULL, 0);
135af57ed9fSAtsushi Murai }
136af57ed9fSAtsushi Murai 
137af57ed9fSAtsushi Murai static void
138af57ed9fSAtsushi Murai CcpSendTerminateReq(fp)
139af57ed9fSAtsushi Murai struct fsm *fp;
140af57ed9fSAtsushi Murai {
141af57ed9fSAtsushi Murai   /* XXX: No code yet */
142af57ed9fSAtsushi Murai }
143af57ed9fSAtsushi Murai 
144af57ed9fSAtsushi Murai static void
145af57ed9fSAtsushi Murai CcpSendTerminateAck(fp)
146af57ed9fSAtsushi Murai struct fsm *fp;
147af57ed9fSAtsushi Murai {
1489c749ffbSPoul-Henning Kamp   LogPrintf(LOG_LCP_BIT, "  %s: SendTerminateAck\n", fp->name);
149af57ed9fSAtsushi Murai   FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0);
150af57ed9fSAtsushi Murai }
151af57ed9fSAtsushi Murai 
152af57ed9fSAtsushi Murai void
153af57ed9fSAtsushi Murai CcpRecvResetReq(fp)
154af57ed9fSAtsushi Murai struct fsm *fp;
155af57ed9fSAtsushi Murai {
156af57ed9fSAtsushi Murai   Pred1Init(2);		/* Initialize Output part */
157af57ed9fSAtsushi Murai }
158af57ed9fSAtsushi Murai 
159af57ed9fSAtsushi Murai static void
160af57ed9fSAtsushi Murai CcpLayerStart(fp)
161af57ed9fSAtsushi Murai struct fsm *fp;
162af57ed9fSAtsushi Murai {
1639c749ffbSPoul-Henning Kamp   LogPrintf(LOG_LCP_BIT, "%s: LayerStart.\n", fp->name);
164af57ed9fSAtsushi Murai }
165af57ed9fSAtsushi Murai 
166af57ed9fSAtsushi Murai static void
167af57ed9fSAtsushi Murai CcpLayerFinish(fp)
168af57ed9fSAtsushi Murai struct fsm *fp;
169af57ed9fSAtsushi Murai {
1709c749ffbSPoul-Henning Kamp   LogPrintf(LOG_LCP_BIT, "%s: LayerFinish.\n", fp->name);
171af57ed9fSAtsushi Murai }
172af57ed9fSAtsushi Murai 
173af57ed9fSAtsushi Murai static void
174af57ed9fSAtsushi Murai CcpLayerDown(fp)
175af57ed9fSAtsushi Murai struct fsm *fp;
176af57ed9fSAtsushi Murai {
1779c749ffbSPoul-Henning Kamp   LogPrintf(LOG_LCP_BIT, "%s: LayerDown.\n", fp->name);
178af57ed9fSAtsushi Murai }
179af57ed9fSAtsushi Murai 
180af57ed9fSAtsushi Murai /*
181af57ed9fSAtsushi Murai  *  Called when CCP has reached to OPEN state
182af57ed9fSAtsushi Murai  */
183af57ed9fSAtsushi Murai static void
184af57ed9fSAtsushi Murai CcpLayerUp(fp)
185af57ed9fSAtsushi Murai struct fsm *fp;
186af57ed9fSAtsushi Murai {
187af57ed9fSAtsushi Murai #ifdef VERBOSE
188af57ed9fSAtsushi Murai   fprintf(stderr, "%s: LayerUp(%d).\r\n", fp->name, fp->state);
189af57ed9fSAtsushi Murai #endif
1909c749ffbSPoul-Henning Kamp   LogPrintf(LOG_LCP_BIT, "%s: LayerUp.\n", fp->name);
1919c749ffbSPoul-Henning Kamp   LogPrintf(LOG_LCP_BIT, "myproto = %d, hisproto = %d\n",
192af57ed9fSAtsushi Murai 	CcpInfo.want_proto, CcpInfo.his_proto);
193af57ed9fSAtsushi Murai   Pred1Init(3);		/* Initialize Input and Output */
194af57ed9fSAtsushi Murai }
195af57ed9fSAtsushi Murai 
196af57ed9fSAtsushi Murai void
197af57ed9fSAtsushi Murai CcpUp()
198af57ed9fSAtsushi Murai {
199af57ed9fSAtsushi Murai   FsmUp(&CcpFsm);
2009c749ffbSPoul-Henning Kamp   LogPrintf(LOG_LCP_BIT, "CCP Up event!!\n");
201af57ed9fSAtsushi Murai }
202af57ed9fSAtsushi Murai 
203af57ed9fSAtsushi Murai void
204af57ed9fSAtsushi Murai CcpOpen()
205af57ed9fSAtsushi Murai {
206af57ed9fSAtsushi Murai   if (Enabled(ConfPred1))
207af57ed9fSAtsushi Murai     FsmOpen(&CcpFsm);
208af57ed9fSAtsushi Murai }
209af57ed9fSAtsushi Murai 
210af57ed9fSAtsushi Murai static void
21153c9f6c0SAtsushi Murai CcpDecodeConfig(cp, plen, mode)
21253c9f6c0SAtsushi Murai u_char *cp;
21353c9f6c0SAtsushi Murai int plen;
214af57ed9fSAtsushi Murai int mode;
215af57ed9fSAtsushi Murai {
21653c9f6c0SAtsushi Murai   int type, length;
217af57ed9fSAtsushi Murai   char tbuff[100];
218af57ed9fSAtsushi Murai 
219af57ed9fSAtsushi Murai   ackp = AckBuff;
220af57ed9fSAtsushi Murai   nakp = NakBuff;
221af57ed9fSAtsushi Murai   rejp = RejBuff;
222af57ed9fSAtsushi Murai 
223af57ed9fSAtsushi Murai   while (plen >= sizeof(struct fsmconfig)) {
224af57ed9fSAtsushi Murai     if (plen < 0)
225af57ed9fSAtsushi Murai       break;
226af57ed9fSAtsushi Murai     type = *cp;
227af57ed9fSAtsushi Murai     length = cp[1];
228af57ed9fSAtsushi Murai     if (type <= TY_BSD)
22999c02d39SWarner Losh       snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes[type], length);
230af57ed9fSAtsushi Murai     else
23199c02d39SWarner Losh       snprintf(tbuff, sizeof(tbuff), " ");
232af57ed9fSAtsushi Murai 
2339c749ffbSPoul-Henning Kamp     LogPrintf(LOG_LCP_BIT, "%s\n", tbuff);
234af57ed9fSAtsushi Murai 
235af57ed9fSAtsushi Murai     switch (type) {
236af57ed9fSAtsushi Murai     case TY_PRED1:
237af57ed9fSAtsushi Murai       switch (mode) {
238af57ed9fSAtsushi Murai       case MODE_REQ:
239af57ed9fSAtsushi Murai 	if (Acceptable(ConfPred1)) {
240af57ed9fSAtsushi Murai 	  bcopy(cp, ackp, length);
241af57ed9fSAtsushi Murai 	  ackp += length;
242af57ed9fSAtsushi Murai 	  CcpInfo.his_proto = type;
243af57ed9fSAtsushi Murai 	} else {
244af57ed9fSAtsushi Murai 	  bcopy(cp, rejp, length);
245af57ed9fSAtsushi Murai 	  rejp += length;
246af57ed9fSAtsushi Murai 	}
247af57ed9fSAtsushi Murai 	break;
248af57ed9fSAtsushi Murai       case MODE_NAK:
249af57ed9fSAtsushi Murai       case MODE_REJ:
250af57ed9fSAtsushi Murai 	CcpInfo.his_reject |= (1 << type);
251af57ed9fSAtsushi Murai 	CcpInfo.want_proto = 0;
252af57ed9fSAtsushi Murai 	break;
253af57ed9fSAtsushi Murai       }
254af57ed9fSAtsushi Murai       break;
255af57ed9fSAtsushi Murai     case TY_BSD:
256af57ed9fSAtsushi Murai     default:
257af57ed9fSAtsushi Murai       CcpInfo.my_reject |= (1 << type);
258af57ed9fSAtsushi Murai       bcopy(cp, rejp, length);
259af57ed9fSAtsushi Murai       rejp += length;
260af57ed9fSAtsushi Murai       break;
261af57ed9fSAtsushi Murai     }
262af57ed9fSAtsushi Murai     plen -= length;
263af57ed9fSAtsushi Murai     cp += length;
264af57ed9fSAtsushi Murai   }
265af57ed9fSAtsushi Murai }
266af57ed9fSAtsushi Murai 
267af57ed9fSAtsushi Murai void
268af57ed9fSAtsushi Murai CcpInput(struct mbuf *bp)
269af57ed9fSAtsushi Murai {
270af57ed9fSAtsushi Murai   if (phase == PHASE_NETWORK)
271af57ed9fSAtsushi Murai     FsmInput(&CcpFsm, bp);
272af57ed9fSAtsushi Murai   else {
273af57ed9fSAtsushi Murai     logprintf("ccp in phase %d\n", phase);
274af57ed9fSAtsushi Murai     pfree(bp);
275af57ed9fSAtsushi Murai   }
276af57ed9fSAtsushi Murai }
277