xref: /freebsd/usr.sbin/ppp/ccp.c (revision af57ed9fdcc4e2a81940fc2243c0d3949fc0e00f)
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  *
20af57ed9fSAtsushi Murai  * $Id:$
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"
31af57ed9fSAtsushi Murai 
32af57ed9fSAtsushi Murai extern void PutConfValue();
33af57ed9fSAtsushi Murai 
34af57ed9fSAtsushi Murai struct ccpstate CcpInfo;
35af57ed9fSAtsushi Murai 
36af57ed9fSAtsushi Murai static void CcpSendConfigReq(struct fsm *);
37af57ed9fSAtsushi Murai static void CcpSendTerminateReq(struct fsm *fp);
38af57ed9fSAtsushi Murai static void CcpSendTerminateAck(struct fsm *fp);
39af57ed9fSAtsushi Murai static void CcpDecodeConfig(struct mbuf *bp, int mode);
40af57ed9fSAtsushi Murai static void CcpLayerStart(struct fsm *);
41af57ed9fSAtsushi Murai static void CcpLayerFinish(struct fsm *);
42af57ed9fSAtsushi Murai static void CcpLayerUp(struct fsm *);
43af57ed9fSAtsushi Murai static void CcpLayerDown(struct fsm *);
44af57ed9fSAtsushi Murai 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 
70af57ed9fSAtsushi Murai static char *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 
79af57ed9fSAtsushi Murai void
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]);
88af57ed9fSAtsushi Murai   printf("Input: %d --> %d,  Output: %d --> %d\n",
89af57ed9fSAtsushi Murai 	icp->orgin, icp->compin, icp->orgout, icp->compout);
90af57ed9fSAtsushi Murai }
91af57ed9fSAtsushi Murai 
92af57ed9fSAtsushi Murai void
93af57ed9fSAtsushi Murai CcpInit()
94af57ed9fSAtsushi Murai {
95af57ed9fSAtsushi Murai   struct ccpstate *icp = &CcpInfo;
96af57ed9fSAtsushi Murai 
97af57ed9fSAtsushi Murai   FsmInit(&CcpFsm);
98af57ed9fSAtsushi Murai   bzero(icp, sizeof(struct ccpstate));
99af57ed9fSAtsushi Murai   if (Enabled(ConfPred1))
100af57ed9fSAtsushi Murai     icp->want_proto = TY_PRED1;
101af57ed9fSAtsushi Murai   CcpFsm.maxconfig = 10;
102af57ed9fSAtsushi Murai }
103af57ed9fSAtsushi Murai 
104af57ed9fSAtsushi Murai static void
105af57ed9fSAtsushi Murai CcpInitRestartCounter(fp)
106af57ed9fSAtsushi Murai struct fsm *fp;
107af57ed9fSAtsushi Murai {
108af57ed9fSAtsushi Murai   fp->FsmTimer.load = 3 * SECTICKS;
109af57ed9fSAtsushi Murai   fp->restart = 5;
110af57ed9fSAtsushi Murai }
111af57ed9fSAtsushi Murai 
112af57ed9fSAtsushi Murai static void
113af57ed9fSAtsushi Murai CcpSendConfigReq(fp)
114af57ed9fSAtsushi Murai struct fsm *fp;
115af57ed9fSAtsushi Murai {
116af57ed9fSAtsushi Murai   u_char *cp;
117af57ed9fSAtsushi Murai   struct ccpstate *icp = &CcpInfo;
118af57ed9fSAtsushi Murai 
119af57ed9fSAtsushi Murai   cp = ReqBuff;
120af57ed9fSAtsushi Murai   LogPrintf(LOG_LCP, "%s: SendConfigReq\n", fp->name);
121af57ed9fSAtsushi Murai   if (icp->want_proto && !REJECTED(icp, TY_PRED1)) {
122af57ed9fSAtsushi Murai     *cp++ = TY_PRED1; *cp++ = 2;
123af57ed9fSAtsushi Murai   }
124af57ed9fSAtsushi Murai   FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff);
125af57ed9fSAtsushi Murai }
126af57ed9fSAtsushi Murai 
127af57ed9fSAtsushi Murai void
128af57ed9fSAtsushi Murai CcpSendResetReq(fp)
129af57ed9fSAtsushi Murai struct fsm *fp;
130af57ed9fSAtsushi Murai {
131af57ed9fSAtsushi Murai   Pred1Init(1);		/* Initialize Input part */
132af57ed9fSAtsushi Murai   LogPrintf(LOG_LCP, "%s: SendResetReq\n", fp->name);
133af57ed9fSAtsushi Murai   FsmOutput(fp, CODE_RESETREQ, fp->reqid, NULL, 0);
134af57ed9fSAtsushi Murai }
135af57ed9fSAtsushi Murai 
136af57ed9fSAtsushi Murai static void
137af57ed9fSAtsushi Murai CcpSendTerminateReq(fp)
138af57ed9fSAtsushi Murai struct fsm *fp;
139af57ed9fSAtsushi Murai {
140af57ed9fSAtsushi Murai   /* XXX: No code yet */
141af57ed9fSAtsushi Murai }
142af57ed9fSAtsushi Murai 
143af57ed9fSAtsushi Murai static void
144af57ed9fSAtsushi Murai CcpSendTerminateAck(fp)
145af57ed9fSAtsushi Murai struct fsm *fp;
146af57ed9fSAtsushi Murai {
147af57ed9fSAtsushi Murai   LogPrintf(LOG_LCP, "  %s: SendTerminateAck\n", fp->name);
148af57ed9fSAtsushi Murai   FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0);
149af57ed9fSAtsushi Murai }
150af57ed9fSAtsushi Murai 
151af57ed9fSAtsushi Murai void
152af57ed9fSAtsushi Murai CcpRecvResetReq(fp)
153af57ed9fSAtsushi Murai struct fsm *fp;
154af57ed9fSAtsushi Murai {
155af57ed9fSAtsushi Murai   Pred1Init(2);		/* Initialize Output part */
156af57ed9fSAtsushi Murai }
157af57ed9fSAtsushi Murai 
158af57ed9fSAtsushi Murai static void
159af57ed9fSAtsushi Murai CcpLayerStart(fp)
160af57ed9fSAtsushi Murai struct fsm *fp;
161af57ed9fSAtsushi Murai {
162af57ed9fSAtsushi Murai   LogPrintf(LOG_LCP, "%s: LayerStart.\n", fp->name);
163af57ed9fSAtsushi Murai }
164af57ed9fSAtsushi Murai 
165af57ed9fSAtsushi Murai static void
166af57ed9fSAtsushi Murai CcpLayerFinish(fp)
167af57ed9fSAtsushi Murai struct fsm *fp;
168af57ed9fSAtsushi Murai {
169af57ed9fSAtsushi Murai   LogPrintf(LOG_LCP, "%s: LayerFinish.\n", fp->name);
170af57ed9fSAtsushi Murai }
171af57ed9fSAtsushi Murai 
172af57ed9fSAtsushi Murai static void
173af57ed9fSAtsushi Murai CcpLayerDown(fp)
174af57ed9fSAtsushi Murai struct fsm *fp;
175af57ed9fSAtsushi Murai {
176af57ed9fSAtsushi Murai   LogPrintf(LOG_LCP, "%s: LayerDown.\n", fp->name);
177af57ed9fSAtsushi Murai }
178af57ed9fSAtsushi Murai 
179af57ed9fSAtsushi Murai /*
180af57ed9fSAtsushi Murai  *  Called when CCP has reached to OPEN state
181af57ed9fSAtsushi Murai  */
182af57ed9fSAtsushi Murai static void
183af57ed9fSAtsushi Murai CcpLayerUp(fp)
184af57ed9fSAtsushi Murai struct fsm *fp;
185af57ed9fSAtsushi Murai {
186af57ed9fSAtsushi Murai #ifdef VERBOSE
187af57ed9fSAtsushi Murai   fprintf(stderr, "%s: LayerUp(%d).\r\n", fp->name, fp->state);
188af57ed9fSAtsushi Murai #endif
189af57ed9fSAtsushi Murai   LogPrintf(LOG_LCP, "%s: LayerUp.\n", fp->name);
190af57ed9fSAtsushi Murai   LogPrintf(LOG_LCP, "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);
199af57ed9fSAtsushi Murai   LogPrintf(LOG_LCP, "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
210af57ed9fSAtsushi Murai CcpDecodeConfig(bp, mode)
211af57ed9fSAtsushi Murai struct mbuf *bp;
212af57ed9fSAtsushi Murai int mode;
213af57ed9fSAtsushi Murai {
214af57ed9fSAtsushi Murai   u_char *cp;
215af57ed9fSAtsushi Murai   int plen, type, length;
216af57ed9fSAtsushi Murai   u_long *lp, compproto;
217af57ed9fSAtsushi Murai   struct compreq *pcomp;
218af57ed9fSAtsushi Murai   struct in_addr ipaddr, dstipaddr;
219af57ed9fSAtsushi Murai   char tbuff[100];
220af57ed9fSAtsushi Murai 
221af57ed9fSAtsushi Murai   plen = plength(bp);
222af57ed9fSAtsushi Murai 
223af57ed9fSAtsushi Murai   cp = MBUF_CTOP(bp);
224af57ed9fSAtsushi Murai   ackp = AckBuff;
225af57ed9fSAtsushi Murai   nakp = NakBuff;
226af57ed9fSAtsushi Murai   rejp = RejBuff;
227af57ed9fSAtsushi Murai 
228af57ed9fSAtsushi Murai   while (plen >= sizeof(struct fsmconfig)) {
229af57ed9fSAtsushi Murai     if (plen < 0)
230af57ed9fSAtsushi Murai       break;
231af57ed9fSAtsushi Murai     type = *cp;
232af57ed9fSAtsushi Murai     length = cp[1];
233af57ed9fSAtsushi Murai     if (type <= TY_BSD)
234af57ed9fSAtsushi Murai       sprintf(tbuff, " %s[%d] ", cftypes[type], length);
235af57ed9fSAtsushi Murai     else
236af57ed9fSAtsushi Murai       sprintf(tbuff, " ");
237af57ed9fSAtsushi Murai 
238af57ed9fSAtsushi Murai     LogPrintf(LOG_LCP, "%s\n", tbuff);
239af57ed9fSAtsushi Murai 
240af57ed9fSAtsushi Murai     switch (type) {
241af57ed9fSAtsushi Murai     case TY_PRED1:
242af57ed9fSAtsushi Murai       switch (mode) {
243af57ed9fSAtsushi Murai       case MODE_REQ:
244af57ed9fSAtsushi Murai 	if (Acceptable(ConfPred1)) {
245af57ed9fSAtsushi Murai 	  bcopy(cp, ackp, length);
246af57ed9fSAtsushi Murai 	  ackp += length;
247af57ed9fSAtsushi Murai 	  CcpInfo.his_proto = type;
248af57ed9fSAtsushi Murai 	} else {
249af57ed9fSAtsushi Murai 	  bcopy(cp, rejp, length);
250af57ed9fSAtsushi Murai 	  rejp += length;
251af57ed9fSAtsushi Murai 	}
252af57ed9fSAtsushi Murai 	break;
253af57ed9fSAtsushi Murai       case MODE_NAK:
254af57ed9fSAtsushi Murai       case MODE_REJ:
255af57ed9fSAtsushi Murai 	CcpInfo.his_reject |= (1 << type);
256af57ed9fSAtsushi Murai 	CcpInfo.want_proto = 0;
257af57ed9fSAtsushi Murai 	break;
258af57ed9fSAtsushi Murai       }
259af57ed9fSAtsushi Murai       break;
260af57ed9fSAtsushi Murai     case TY_BSD:
261af57ed9fSAtsushi Murai     default:
262af57ed9fSAtsushi Murai       CcpInfo.my_reject |= (1 << type);
263af57ed9fSAtsushi Murai       bcopy(cp, rejp, length);
264af57ed9fSAtsushi Murai       rejp += length;
265af57ed9fSAtsushi Murai       break;
266af57ed9fSAtsushi Murai     }
267af57ed9fSAtsushi Murai     plen -= length;
268af57ed9fSAtsushi Murai     cp += length;
269af57ed9fSAtsushi Murai   }
270af57ed9fSAtsushi Murai }
271af57ed9fSAtsushi Murai 
272af57ed9fSAtsushi Murai void
273af57ed9fSAtsushi Murai CcpInput(struct mbuf *bp)
274af57ed9fSAtsushi Murai {
275af57ed9fSAtsushi Murai   if (phase == PHASE_NETWORK)
276af57ed9fSAtsushi Murai     FsmInput(&CcpFsm, bp);
277af57ed9fSAtsushi Murai   else {
278af57ed9fSAtsushi Murai     logprintf("ccp in phase %d\n", phase);
279af57ed9fSAtsushi Murai     pfree(bp);
280af57ed9fSAtsushi Murai   }
281af57ed9fSAtsushi Murai }
282