xref: /freebsd/usr.sbin/ppp/ccp.c (revision 9780ef311da5ca37faea2cb23bcb7d2cf0dc96e9)
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  *
209780ef31SBrian Somers  * $Id: ccp.c,v 1.17 1997/10/26 01:02:10 brian Exp $
21af57ed9fSAtsushi Murai  *
22af57ed9fSAtsushi Murai  *	TODO:
23af57ed9fSAtsushi Murai  *		o Support other compression protocols
24af57ed9fSAtsushi Murai  */
2575240ed1SBrian Somers #include <sys/param.h>
2675240ed1SBrian Somers #include <netinet/in.h>
2775240ed1SBrian Somers 
2875240ed1SBrian Somers #include <stdio.h>
2975240ed1SBrian Somers #include <string.h>
3075240ed1SBrian Somers 
3175240ed1SBrian Somers #include "mbuf.h"
3275240ed1SBrian Somers #include "log.h"
3375240ed1SBrian Somers #include "defs.h"
3475240ed1SBrian Somers #include "timer.h"
35af57ed9fSAtsushi Murai #include "fsm.h"
36af57ed9fSAtsushi Murai #include "lcpproto.h"
37af57ed9fSAtsushi Murai #include "lcp.h"
38af57ed9fSAtsushi Murai #include "ccp.h"
39af57ed9fSAtsushi Murai #include "phase.h"
406ed9fb2fSBrian Somers #include "loadalias.h"
4175240ed1SBrian Somers #include "command.h"
42af57ed9fSAtsushi Murai #include "vars.h"
43ed6a16c1SPoul-Henning Kamp #include "pred.h"
44af57ed9fSAtsushi Murai 
45af57ed9fSAtsushi Murai struct ccpstate CcpInfo;
46af57ed9fSAtsushi Murai 
47927145beSBrian Somers static void CcpSendConfigReq(struct fsm *);
4875240ed1SBrian Somers static void CcpSendTerminateReq(struct fsm *);
4975240ed1SBrian Somers static void CcpSendTerminateAck(struct fsm *);
5075240ed1SBrian Somers static void CcpDecodeConfig(u_char *, int, int);
51927145beSBrian Somers static void CcpLayerStart(struct fsm *);
52927145beSBrian Somers static void CcpLayerFinish(struct fsm *);
53927145beSBrian Somers static void CcpLayerUp(struct fsm *);
54927145beSBrian Somers static void CcpLayerDown(struct fsm *);
55927145beSBrian Somers static void CcpInitRestartCounter(struct fsm *);
56af57ed9fSAtsushi Murai 
57af57ed9fSAtsushi Murai #define	REJECTED(p, x)	(p->his_reject & (1<<x))
58af57ed9fSAtsushi Murai 
59af57ed9fSAtsushi Murai struct fsm CcpFsm = {
60af57ed9fSAtsushi Murai   "CCP",
61af57ed9fSAtsushi Murai   PROTO_CCP,
62af57ed9fSAtsushi Murai   CCP_MAXCODE,
63af57ed9fSAtsushi Murai   OPEN_ACTIVE,
64af57ed9fSAtsushi Murai   ST_INITIAL,
65af57ed9fSAtsushi Murai   0, 0, 0,
66af57ed9fSAtsushi Murai   0,
67af57ed9fSAtsushi Murai   {0, 0, 0, NULL, NULL, NULL},
68cb611434SBrian Somers   {0, 0, 0, NULL, NULL, NULL},
69cb611434SBrian Somers   LogCCP,
70af57ed9fSAtsushi Murai 
71af57ed9fSAtsushi Murai   CcpLayerUp,
72af57ed9fSAtsushi Murai   CcpLayerDown,
73af57ed9fSAtsushi Murai   CcpLayerStart,
74af57ed9fSAtsushi Murai   CcpLayerFinish,
75af57ed9fSAtsushi Murai   CcpInitRestartCounter,
76af57ed9fSAtsushi Murai   CcpSendConfigReq,
77af57ed9fSAtsushi Murai   CcpSendTerminateReq,
78af57ed9fSAtsushi Murai   CcpSendTerminateAck,
79af57ed9fSAtsushi Murai   CcpDecodeConfig,
80af57ed9fSAtsushi Murai };
81af57ed9fSAtsushi Murai 
82e53374eaSPoul-Henning Kamp static char const *cftypes[] = {
83af57ed9fSAtsushi Murai    /*  0 */ "OUI", "PRED1", "PRED2", "PUDDLE",
84af57ed9fSAtsushi Murai    /*  4 */ "???", "???", "???", "???",
85af57ed9fSAtsushi Murai    /*  8 */ "???", "???", "???", "???",
86af57ed9fSAtsushi Murai    /* 12 */ "???", "???", "???", "???",
87af57ed9fSAtsushi Murai    /* 16 */ "HWPPC", "STAC", "MSPPC", "GAND",
88af57ed9fSAtsushi Murai    /* 20 */ "V42BIS", "BSD",
89af57ed9fSAtsushi Murai };
90af57ed9fSAtsushi Murai 
91274e766cSBrian Somers int
92af57ed9fSAtsushi Murai ReportCcpStatus()
93af57ed9fSAtsushi Murai {
94af57ed9fSAtsushi Murai   struct ccpstate *icp = &CcpInfo;
95af57ed9fSAtsushi Murai   struct fsm *fp = &CcpFsm;
96af57ed9fSAtsushi Murai 
97927145beSBrian Somers   if (VarTerm) {
98927145beSBrian Somers     fprintf(VarTerm, "%s [%s]\n", fp->name, StateNames[fp->state]);
99927145beSBrian Somers     fprintf(VarTerm, "myproto = %s, hisproto = %s\n",
100af57ed9fSAtsushi Murai 	    cftypes[icp->want_proto], cftypes[icp->his_proto]);
101927145beSBrian Somers     fprintf(VarTerm, "Input: %ld --> %ld,  Output: %ld --> %ld\n",
102af57ed9fSAtsushi Murai 	    icp->orgin, icp->compin, icp->orgout, icp->compout);
103927145beSBrian Somers   }
104274e766cSBrian Somers   return 0;
105af57ed9fSAtsushi Murai }
106af57ed9fSAtsushi Murai 
107af57ed9fSAtsushi Murai void
108af57ed9fSAtsushi Murai CcpInit()
109af57ed9fSAtsushi Murai {
110af57ed9fSAtsushi Murai   struct ccpstate *icp = &CcpInfo;
111af57ed9fSAtsushi Murai 
112af57ed9fSAtsushi Murai   FsmInit(&CcpFsm);
11375240ed1SBrian Somers   memset(icp, '\0', sizeof(struct ccpstate));
114af57ed9fSAtsushi Murai   if (Enabled(ConfPred1))
115af57ed9fSAtsushi Murai     icp->want_proto = TY_PRED1;
116af57ed9fSAtsushi Murai   CcpFsm.maxconfig = 10;
117af57ed9fSAtsushi Murai }
118af57ed9fSAtsushi Murai 
119af57ed9fSAtsushi Murai static void
120944f7098SBrian Somers CcpInitRestartCounter(struct fsm *fp)
121af57ed9fSAtsushi Murai {
12253c9f6c0SAtsushi Murai   fp->FsmTimer.load = VarRetryTimeout * SECTICKS;
123af57ed9fSAtsushi Murai   fp->restart = 5;
124af57ed9fSAtsushi Murai }
125af57ed9fSAtsushi Murai 
126af57ed9fSAtsushi Murai static void
127944f7098SBrian Somers CcpSendConfigReq(struct fsm *fp)
128af57ed9fSAtsushi Murai {
129af57ed9fSAtsushi Murai   u_char *cp;
130af57ed9fSAtsushi Murai   struct ccpstate *icp = &CcpInfo;
131af57ed9fSAtsushi Murai 
132af57ed9fSAtsushi Murai   cp = ReqBuff;
133cb611434SBrian Somers   LogPrintf(LogCCP, "CcpSendConfigReq\n");
134af57ed9fSAtsushi Murai   if (icp->want_proto && !REJECTED(icp, TY_PRED1)) {
135944f7098SBrian Somers     *cp++ = TY_PRED1;
136944f7098SBrian Somers     *cp++ = 2;
137af57ed9fSAtsushi Murai   }
138af57ed9fSAtsushi Murai   FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff);
139af57ed9fSAtsushi Murai }
140af57ed9fSAtsushi Murai 
141af57ed9fSAtsushi Murai void
142944f7098SBrian Somers CcpSendResetReq(struct fsm *fp)
143af57ed9fSAtsushi Murai {
144cb611434SBrian Somers   LogPrintf(LogCCP, "CcpSendResetReq\n");
145af57ed9fSAtsushi Murai   FsmOutput(fp, CODE_RESETREQ, fp->reqid, NULL, 0);
146af57ed9fSAtsushi Murai }
147af57ed9fSAtsushi Murai 
148af57ed9fSAtsushi Murai static void
149944f7098SBrian Somers CcpSendTerminateReq(struct fsm *fp)
150af57ed9fSAtsushi Murai {
151af57ed9fSAtsushi Murai   /* XXX: No code yet */
152af57ed9fSAtsushi Murai }
153af57ed9fSAtsushi Murai 
154af57ed9fSAtsushi Murai static void
155944f7098SBrian Somers CcpSendTerminateAck(struct fsm *fp)
156af57ed9fSAtsushi Murai {
157cb611434SBrian Somers   LogPrintf(LogCCP, "CcpSendTerminateAck\n");
158af57ed9fSAtsushi Murai   FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0);
159af57ed9fSAtsushi Murai }
160af57ed9fSAtsushi Murai 
161af57ed9fSAtsushi Murai void
162944f7098SBrian Somers CcpRecvResetReq(struct fsm *fp)
163af57ed9fSAtsushi Murai {
164af57ed9fSAtsushi Murai   Pred1Init(2);			/* Initialize Output part */
165af57ed9fSAtsushi Murai }
166af57ed9fSAtsushi Murai 
167af57ed9fSAtsushi Murai static void
168944f7098SBrian Somers CcpLayerStart(struct fsm *fp)
169af57ed9fSAtsushi Murai {
170cb611434SBrian Somers   LogPrintf(LogCCP, "CcpLayerStart.\n");
171af57ed9fSAtsushi Murai }
172af57ed9fSAtsushi Murai 
173af57ed9fSAtsushi Murai static void
174944f7098SBrian Somers CcpLayerFinish(struct fsm *fp)
175af57ed9fSAtsushi Murai {
176cb611434SBrian Somers   LogPrintf(LogCCP, "CcpLayerFinish.\n");
177af57ed9fSAtsushi Murai }
178af57ed9fSAtsushi Murai 
179af57ed9fSAtsushi Murai static void
180944f7098SBrian Somers CcpLayerDown(struct fsm *fp)
181af57ed9fSAtsushi Murai {
182cb611434SBrian Somers   LogPrintf(LogCCP, "CcpLayerDown.\n");
183af57ed9fSAtsushi Murai }
184af57ed9fSAtsushi Murai 
185af57ed9fSAtsushi Murai /*
186af57ed9fSAtsushi Murai  *  Called when CCP has reached to OPEN state
187af57ed9fSAtsushi Murai  */
188af57ed9fSAtsushi Murai static void
189944f7098SBrian Somers CcpLayerUp(struct fsm *fp)
190af57ed9fSAtsushi Murai {
191cb611434SBrian Somers   LogPrintf(LogCCP, "CcpLayerUp(%d).\n", fp->state);
192cb611434SBrian Somers   LogPrintf(LogCCP, "myproto = %d, hisproto = %d\n",
193af57ed9fSAtsushi Murai 	    CcpInfo.want_proto, CcpInfo.his_proto);
194af57ed9fSAtsushi Murai   Pred1Init(3);			/* Initialize Input and Output */
195af57ed9fSAtsushi Murai }
196af57ed9fSAtsushi Murai 
197af57ed9fSAtsushi Murai void
198af57ed9fSAtsushi Murai CcpUp()
199af57ed9fSAtsushi Murai {
200af57ed9fSAtsushi Murai   FsmUp(&CcpFsm);
201cb611434SBrian Somers   LogPrintf(LogCCP, "CCP Up event!!\n");
202af57ed9fSAtsushi Murai }
203af57ed9fSAtsushi Murai 
204af57ed9fSAtsushi Murai void
205af57ed9fSAtsushi Murai CcpOpen()
206af57ed9fSAtsushi Murai {
207af57ed9fSAtsushi Murai   if (Enabled(ConfPred1))
208af57ed9fSAtsushi Murai     FsmOpen(&CcpFsm);
209af57ed9fSAtsushi Murai }
210af57ed9fSAtsushi Murai 
211af57ed9fSAtsushi Murai static void
2129780ef31SBrian Somers CcpDecodeConfig(u_char *cp, int plen, int mode_type)
213af57ed9fSAtsushi Murai {
21453c9f6c0SAtsushi Murai   int type, length;
215af57ed9fSAtsushi Murai   char tbuff[100];
216af57ed9fSAtsushi Murai 
217af57ed9fSAtsushi Murai   ackp = AckBuff;
218af57ed9fSAtsushi Murai   nakp = NakBuff;
219af57ed9fSAtsushi Murai   rejp = RejBuff;
220af57ed9fSAtsushi Murai 
221af57ed9fSAtsushi Murai   while (plen >= sizeof(struct fsmconfig)) {
222af57ed9fSAtsushi Murai     if (plen < 0)
223af57ed9fSAtsushi Murai       break;
224af57ed9fSAtsushi Murai     type = *cp;
225af57ed9fSAtsushi Murai     length = cp[1];
226af57ed9fSAtsushi Murai     if (type <= TY_BSD)
22799c02d39SWarner Losh       snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes[type], length);
228af57ed9fSAtsushi Murai     else
22999c02d39SWarner Losh       snprintf(tbuff, sizeof(tbuff), " ");
230af57ed9fSAtsushi Murai 
231cb611434SBrian Somers     LogPrintf(LogCCP, "%s\n", tbuff);
232af57ed9fSAtsushi Murai 
233af57ed9fSAtsushi Murai     switch (type) {
234af57ed9fSAtsushi Murai     case TY_PRED1:
2359780ef31SBrian Somers       switch (mode_type) {
236af57ed9fSAtsushi Murai       case MODE_REQ:
237af57ed9fSAtsushi Murai 	if (Acceptable(ConfPred1)) {
23875240ed1SBrian Somers 	  memcpy(ackp, cp, length);
239af57ed9fSAtsushi Murai 	  ackp += length;
240af57ed9fSAtsushi Murai 	  CcpInfo.his_proto = type;
241af57ed9fSAtsushi Murai 	} else {
24275240ed1SBrian Somers 	  memcpy(rejp, cp, length);
243af57ed9fSAtsushi Murai 	  rejp += length;
244af57ed9fSAtsushi Murai 	}
245af57ed9fSAtsushi Murai 	break;
246af57ed9fSAtsushi Murai       case MODE_NAK:
247af57ed9fSAtsushi Murai       case MODE_REJ:
248af57ed9fSAtsushi Murai 	CcpInfo.his_reject |= (1 << type);
249af57ed9fSAtsushi Murai 	CcpInfo.want_proto = 0;
250af57ed9fSAtsushi Murai 	break;
251af57ed9fSAtsushi Murai       }
252af57ed9fSAtsushi Murai       break;
253af57ed9fSAtsushi Murai     case TY_BSD:
254af57ed9fSAtsushi Murai     default:
255af57ed9fSAtsushi Murai       CcpInfo.my_reject |= (1 << type);
25675240ed1SBrian Somers       memcpy(rejp, cp, length);
257af57ed9fSAtsushi Murai       rejp += length;
258af57ed9fSAtsushi Murai       break;
259af57ed9fSAtsushi Murai     }
260af57ed9fSAtsushi Murai     plen -= length;
261af57ed9fSAtsushi Murai     cp += length;
262af57ed9fSAtsushi Murai   }
263af57ed9fSAtsushi Murai }
264af57ed9fSAtsushi Murai 
265af57ed9fSAtsushi Murai void
266af57ed9fSAtsushi Murai CcpInput(struct mbuf *bp)
267af57ed9fSAtsushi Murai {
268af57ed9fSAtsushi Murai   if (phase == PHASE_NETWORK)
269af57ed9fSAtsushi Murai     FsmInput(&CcpFsm, bp);
270af57ed9fSAtsushi Murai   else {
27129a6597cSBrian Somers     if (phase > PHASE_NETWORK)
272927145beSBrian Somers       LogPrintf(LogERROR, "Unexpected CCP in phase %d\n", phase);
273af57ed9fSAtsushi Murai     pfree(bp);
274af57ed9fSAtsushi Murai   }
275af57ed9fSAtsushi Murai }
276