xref: /freebsd/usr.sbin/ppp/ccp.c (revision 247ab36d2858e9c2e6310d7dde2134d0fd8a1bdc)
11ae349f5Scvs2svn /*
21ae349f5Scvs2svn  *	   PPP Compression Control Protocol (CCP) Module
31ae349f5Scvs2svn  *
41ae349f5Scvs2svn  *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
51ae349f5Scvs2svn  *
61ae349f5Scvs2svn  *   Copyright (C) 1994, Internet Initiative Japan, Inc. All rights reserverd.
71ae349f5Scvs2svn  *
81ae349f5Scvs2svn  * Redistribution and use in source and binary forms are permitted
91ae349f5Scvs2svn  * provided that the above copyright notice and this paragraph are
101ae349f5Scvs2svn  * duplicated in all such forms and that any documentation,
111ae349f5Scvs2svn  * advertising materials, and other materials related to such
121ae349f5Scvs2svn  * distribution and use acknowledge that the software was developed
131ae349f5Scvs2svn  * by the Internet Initiative Japan, Inc.  The name of the
141ae349f5Scvs2svn  * IIJ may not be used to endorse or promote products derived
151ae349f5Scvs2svn  * from this software without specific prior written permission.
161ae349f5Scvs2svn  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
171ae349f5Scvs2svn  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
181ae349f5Scvs2svn  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
191ae349f5Scvs2svn  *
20247ab36dSBrian Somers  * $Id: ccp.c,v 1.30.2.1 1998/01/29 00:49:13 brian Exp $
211ae349f5Scvs2svn  *
221ae349f5Scvs2svn  *	TODO:
231ae349f5Scvs2svn  *		o Support other compression protocols
241ae349f5Scvs2svn  */
251ae349f5Scvs2svn #include <sys/param.h>
261ae349f5Scvs2svn #include <netinet/in.h>
271ae349f5Scvs2svn 
281ae349f5Scvs2svn #include <stdio.h>
291ae349f5Scvs2svn #include <string.h>
301ae349f5Scvs2svn 
311ae349f5Scvs2svn #include "command.h"
321ae349f5Scvs2svn #include "mbuf.h"
331ae349f5Scvs2svn #include "log.h"
341ae349f5Scvs2svn #include "defs.h"
351ae349f5Scvs2svn #include "timer.h"
361ae349f5Scvs2svn #include "fsm.h"
371ae349f5Scvs2svn #include "lcpproto.h"
381ae349f5Scvs2svn #include "lcp.h"
391ae349f5Scvs2svn #include "ccp.h"
401ae349f5Scvs2svn #include "phase.h"
411ae349f5Scvs2svn #include "loadalias.h"
421ae349f5Scvs2svn #include "vars.h"
431ae349f5Scvs2svn #include "pred.h"
441ae349f5Scvs2svn #include "deflate.h"
451ae349f5Scvs2svn 
46247ab36dSBrian Somers struct ccpstate CcpInfo = { -1, -1, -1, -1, -1, -1 };
471ae349f5Scvs2svn 
481ae349f5Scvs2svn static void CcpSendConfigReq(struct fsm *);
491ae349f5Scvs2svn static void CcpSendTerminateReq(struct fsm *);
501ae349f5Scvs2svn static void CcpSendTerminateAck(struct fsm *);
511ae349f5Scvs2svn static void CcpDecodeConfig(u_char *, int, int);
521ae349f5Scvs2svn static void CcpLayerStart(struct fsm *);
531ae349f5Scvs2svn static void CcpLayerFinish(struct fsm *);
541ae349f5Scvs2svn static void CcpLayerUp(struct fsm *);
551ae349f5Scvs2svn static void CcpLayerDown(struct fsm *);
561ae349f5Scvs2svn static void CcpInitRestartCounter(struct fsm *);
571ae349f5Scvs2svn 
581ae349f5Scvs2svn struct fsm CcpFsm = {
591ae349f5Scvs2svn   "CCP",
601ae349f5Scvs2svn   PROTO_CCP,
611ae349f5Scvs2svn   CCP_MAXCODE,
621ae349f5Scvs2svn   0,
631ae349f5Scvs2svn   ST_INITIAL,
641ae349f5Scvs2svn   0, 0, 0,
651ae349f5Scvs2svn   {0, 0, 0, NULL, NULL, NULL},	/* FSM timer */
661ae349f5Scvs2svn   {0, 0, 0, NULL, NULL, NULL},	/* Open timer */
671ae349f5Scvs2svn   {0, 0, 0, NULL, NULL, NULL},	/* Stopped timer */
681ae349f5Scvs2svn   LogCCP,
691ae349f5Scvs2svn 
7063b73463SBrian Somers   NULL,
7163b73463SBrian Somers 
721ae349f5Scvs2svn   CcpLayerUp,
731ae349f5Scvs2svn   CcpLayerDown,
741ae349f5Scvs2svn   CcpLayerStart,
751ae349f5Scvs2svn   CcpLayerFinish,
761ae349f5Scvs2svn   CcpInitRestartCounter,
771ae349f5Scvs2svn   CcpSendConfigReq,
781ae349f5Scvs2svn   CcpSendTerminateReq,
791ae349f5Scvs2svn   CcpSendTerminateAck,
801ae349f5Scvs2svn   CcpDecodeConfig,
811ae349f5Scvs2svn };
821ae349f5Scvs2svn 
831ae349f5Scvs2svn static char const *cftypes[] = {
841ae349f5Scvs2svn   /* Check out the latest ``Compression Control Protocol'' rfc (rfc1962.txt) */
851ae349f5Scvs2svn   "OUI",		/* 0: OUI */
861ae349f5Scvs2svn   "PRED1",		/* 1: Predictor type 1 */
871ae349f5Scvs2svn   "PRED2",		/* 2: Predictor type 2 */
881ae349f5Scvs2svn   "PUDDLE",		/* 3: Puddle Jumber */
891ae349f5Scvs2svn   "???", "???", "???", "???", "???", "???",
901ae349f5Scvs2svn   "???", "???", "???", "???", "???", "???",
911ae349f5Scvs2svn   "HWPPC",		/* 16: Hewlett-Packard PPC */
921ae349f5Scvs2svn   "STAC",		/* 17: Stac Electronics LZS (rfc1974) */
931ae349f5Scvs2svn   "MSPPC",		/* 18: Microsoft PPC */
941ae349f5Scvs2svn   "GAND",		/* 19: Gandalf FZA (rfc1993) */
951ae349f5Scvs2svn   "V42BIS",		/* 20: ARG->DATA.42bis compression */
961ae349f5Scvs2svn   "BSD",		/* 21: BSD LZW Compress */
971ae349f5Scvs2svn   "???",
981ae349f5Scvs2svn   "LZS-DCP",		/* 23: LZS-DCP Compression Protocol (rfc1967) */
991ae349f5Scvs2svn   "MAGNALINK/DEFLATE",	/* 24: Magnalink Variable Resource (rfc1975) */
1001ae349f5Scvs2svn 			/* 24: Deflate (according to pppd-2.3.1) */
1011ae349f5Scvs2svn   "DCE",		/* 25: Data Circuit-Terminating Equip (rfc1976) */
1021ae349f5Scvs2svn   "DEFLATE",		/* 26: Deflate (rfc1979) */
1031ae349f5Scvs2svn };
1041ae349f5Scvs2svn 
1051ae349f5Scvs2svn #define NCFTYPES (sizeof cftypes/sizeof cftypes[0])
1061ae349f5Scvs2svn 
1071ae349f5Scvs2svn static const char *
1081ae349f5Scvs2svn protoname(int proto)
1091ae349f5Scvs2svn {
1101ae349f5Scvs2svn   if (proto < 0 || proto > NCFTYPES)
1111ae349f5Scvs2svn     return "none";
1121ae349f5Scvs2svn   return cftypes[proto];
1131ae349f5Scvs2svn }
1141ae349f5Scvs2svn 
1151ae349f5Scvs2svn /* We support these algorithms, and Req them in the given order */
1161ae349f5Scvs2svn static const struct ccp_algorithm *algorithm[] = {
1171ae349f5Scvs2svn   &DeflateAlgorithm,
1181ae349f5Scvs2svn   &Pred1Algorithm,
1191ae349f5Scvs2svn   &PppdDeflateAlgorithm
1201ae349f5Scvs2svn };
1211ae349f5Scvs2svn 
1221ae349f5Scvs2svn #define NALGORITHMS (sizeof algorithm/sizeof algorithm[0])
1231ae349f5Scvs2svn 
1241ae349f5Scvs2svn int
1251ae349f5Scvs2svn ReportCcpStatus(struct cmdargs const *arg)
1261ae349f5Scvs2svn {
1271ae349f5Scvs2svn   if (VarTerm) {
1281ae349f5Scvs2svn     fprintf(VarTerm, "%s [%s]\n", CcpFsm.name, StateNames[CcpFsm.state]);
1291ae349f5Scvs2svn     fprintf(VarTerm, "My protocol = %s, His protocol = %s\n",
1301ae349f5Scvs2svn             protoname(CcpInfo.my_proto), protoname(CcpInfo.his_proto));
1311ae349f5Scvs2svn     fprintf(VarTerm, "Output: %ld --> %ld,  Input: %ld --> %ld\n",
1321ae349f5Scvs2svn             CcpInfo.uncompout, CcpInfo.compout,
1331ae349f5Scvs2svn             CcpInfo.compin, CcpInfo.uncompin);
1341ae349f5Scvs2svn   }
1351ae349f5Scvs2svn   return 0;
1361ae349f5Scvs2svn }
1371ae349f5Scvs2svn 
1381ae349f5Scvs2svn static void
1391ae349f5Scvs2svn ccpstateInit(void)
1401ae349f5Scvs2svn {
1411ae349f5Scvs2svn   if (CcpInfo.in_init)
142247ab36dSBrian Somers     (*algorithm[CcpInfo.in_algorithm]->i.Term)();
1431ae349f5Scvs2svn   if (CcpInfo.out_init)
144247ab36dSBrian Somers     (*algorithm[CcpInfo.out_algorithm]->o.Term)();
1451ae349f5Scvs2svn   memset(&CcpInfo, '\0', sizeof CcpInfo);
146247ab36dSBrian Somers   CcpInfo.in_algorithm = CcpInfo.out_algorithm = -1;
1471ae349f5Scvs2svn   CcpInfo.his_proto = CcpInfo.my_proto = -1;
1481ae349f5Scvs2svn   CcpInfo.reset_sent = CcpInfo.last_reset = -1;
1491ae349f5Scvs2svn }
1501ae349f5Scvs2svn 
1511ae349f5Scvs2svn void
15263b73463SBrian Somers CcpInit(struct physical *physical)
1531ae349f5Scvs2svn {
15463b73463SBrian Somers   FsmInit(&CcpFsm, physical);
1551ae349f5Scvs2svn   ccpstateInit();
1561ae349f5Scvs2svn   CcpFsm.maxconfig = 10;
1571ae349f5Scvs2svn }
1581ae349f5Scvs2svn 
1591ae349f5Scvs2svn static void
1601ae349f5Scvs2svn CcpInitRestartCounter(struct fsm *fp)
1611ae349f5Scvs2svn {
1621ae349f5Scvs2svn   fp->FsmTimer.load = VarRetryTimeout * SECTICKS;
1631ae349f5Scvs2svn   fp->restart = 5;
1641ae349f5Scvs2svn }
1651ae349f5Scvs2svn 
1661ae349f5Scvs2svn static void
1671ae349f5Scvs2svn CcpSendConfigReq(struct fsm *fp)
1681ae349f5Scvs2svn {
1691ae349f5Scvs2svn   u_char *cp;
1701ae349f5Scvs2svn   int f;
1711ae349f5Scvs2svn 
1721ae349f5Scvs2svn   LogPrintf(LogCCP, "CcpSendConfigReq\n");
1731ae349f5Scvs2svn   cp = ReqBuff;
1741ae349f5Scvs2svn   CcpInfo.my_proto = -1;
175247ab36dSBrian Somers   CcpInfo.out_algorithm = -1;
1761ae349f5Scvs2svn   for (f = 0; f < NALGORITHMS; f++)
1771ae349f5Scvs2svn     if (Enabled(algorithm[f]->Conf) && !REJECTED(&CcpInfo, algorithm[f]->id)) {
1781ae349f5Scvs2svn       struct lcp_opt o;
1791ae349f5Scvs2svn 
1801ae349f5Scvs2svn       (*algorithm[f]->o.Get)(&o);
1811ae349f5Scvs2svn       cp += LcpPutConf(LogCCP, cp, &o, cftypes[o.id],
1821ae349f5Scvs2svn                        (*algorithm[f]->Disp)(&o));
1831ae349f5Scvs2svn       CcpInfo.my_proto = o.id;
184247ab36dSBrian Somers       CcpInfo.out_algorithm = f;
1851ae349f5Scvs2svn     }
1861ae349f5Scvs2svn   FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff);
1871ae349f5Scvs2svn }
1881ae349f5Scvs2svn 
1891ae349f5Scvs2svn void
1901ae349f5Scvs2svn CcpSendResetReq(struct fsm *fp)
1911ae349f5Scvs2svn {
1921ae349f5Scvs2svn   LogPrintf(LogCCP, "SendResetReq(%d)\n", fp->reqid);
1931ae349f5Scvs2svn   CcpInfo.reset_sent = fp->reqid;
1941ae349f5Scvs2svn   CcpInfo.last_reset = -1;
1951ae349f5Scvs2svn   FsmOutput(fp, CODE_RESETREQ, fp->reqid, NULL, 0);
1961ae349f5Scvs2svn }
1971ae349f5Scvs2svn 
1981ae349f5Scvs2svn static void
1991ae349f5Scvs2svn CcpSendTerminateReq(struct fsm *fp)
2001ae349f5Scvs2svn {
201247ab36dSBrian Somers   /* Fsm has just send a terminate request */
2021ae349f5Scvs2svn }
2031ae349f5Scvs2svn 
2041ae349f5Scvs2svn static void
2051ae349f5Scvs2svn CcpSendTerminateAck(struct fsm *fp)
2061ae349f5Scvs2svn {
2071ae349f5Scvs2svn   LogPrintf(LogCCP, "CcpSendTerminateAck\n");
2081ae349f5Scvs2svn   FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0);
2091ae349f5Scvs2svn }
2101ae349f5Scvs2svn 
2111ae349f5Scvs2svn void
2121ae349f5Scvs2svn CcpRecvResetReq(struct fsm *fp)
2131ae349f5Scvs2svn {
214247ab36dSBrian Somers   if (CcpInfo.out_init)
215247ab36dSBrian Somers     (*algorithm[CcpInfo.out_algorithm]->o.Reset)();
2161ae349f5Scvs2svn }
2171ae349f5Scvs2svn 
2181ae349f5Scvs2svn static void
2191ae349f5Scvs2svn CcpLayerStart(struct fsm *fp)
2201ae349f5Scvs2svn {
2211ae349f5Scvs2svn   LogPrintf(LogCCP, "CcpLayerStart.\n");
2221ae349f5Scvs2svn }
2231ae349f5Scvs2svn 
2241ae349f5Scvs2svn static void
2251ae349f5Scvs2svn CcpLayerFinish(struct fsm *fp)
2261ae349f5Scvs2svn {
2271ae349f5Scvs2svn   LogPrintf(LogCCP, "CcpLayerFinish.\n");
2281ae349f5Scvs2svn   ccpstateInit();
2291ae349f5Scvs2svn }
2301ae349f5Scvs2svn 
2311ae349f5Scvs2svn static void
2321ae349f5Scvs2svn CcpLayerDown(struct fsm *fp)
2331ae349f5Scvs2svn {
2341ae349f5Scvs2svn   LogPrintf(LogCCP, "CcpLayerDown.\n");
2351ae349f5Scvs2svn   ccpstateInit();
2361ae349f5Scvs2svn }
2371ae349f5Scvs2svn 
2381ae349f5Scvs2svn /*
2391ae349f5Scvs2svn  *  Called when CCP has reached the OPEN state
2401ae349f5Scvs2svn  */
2411ae349f5Scvs2svn static void
2421ae349f5Scvs2svn CcpLayerUp(struct fsm *fp)
2431ae349f5Scvs2svn {
2441ae349f5Scvs2svn   LogPrintf(LogCCP, "CcpLayerUp(%d).\n", fp->state);
245247ab36dSBrian Somers   if (!CcpInfo.in_init && CcpInfo.in_algorithm >= 0 &&
246247ab36dSBrian Somers       CcpInfo.in_algorithm < NALGORITHMS)
247247ab36dSBrian Somers     if ((*algorithm[CcpInfo.in_algorithm]->i.Init)())
248247ab36dSBrian Somers       CcpInfo.in_init = 1;
249247ab36dSBrian Somers     else {
250247ab36dSBrian Somers       LogPrintf(LogERROR, "%s (in) initialisation failure\n",
251247ab36dSBrian Somers                 protoname(CcpInfo.his_proto));
252247ab36dSBrian Somers       CcpInfo.his_proto = CcpInfo.my_proto = -1;
253247ab36dSBrian Somers       FsmClose(fp);
254247ab36dSBrian Somers     }
255247ab36dSBrian Somers   if (!CcpInfo.out_init && CcpInfo.out_algorithm >= 0 &&
256247ab36dSBrian Somers       CcpInfo.out_algorithm < NALGORITHMS)
257247ab36dSBrian Somers     if ((*algorithm[CcpInfo.out_algorithm]->o.Init)())
258247ab36dSBrian Somers       CcpInfo.out_init = 1;
259247ab36dSBrian Somers     else {
260247ab36dSBrian Somers       LogPrintf(LogERROR, "%s (out) initialisation failure\n",
261247ab36dSBrian Somers                 protoname(CcpInfo.my_proto));
262247ab36dSBrian Somers       CcpInfo.his_proto = CcpInfo.my_proto = -1;
263247ab36dSBrian Somers       FsmClose(fp);
264247ab36dSBrian Somers     }
2651ae349f5Scvs2svn   LogPrintf(LogCCP, "Out = %s[%d], In = %s[%d]\n",
2661ae349f5Scvs2svn             protoname(CcpInfo.my_proto), CcpInfo.my_proto,
2671ae349f5Scvs2svn             protoname(CcpInfo.his_proto), CcpInfo.his_proto);
2681ae349f5Scvs2svn }
2691ae349f5Scvs2svn 
2701ae349f5Scvs2svn void
2711ae349f5Scvs2svn CcpUp()
2721ae349f5Scvs2svn {
2731ae349f5Scvs2svn   FsmUp(&CcpFsm);
2741ae349f5Scvs2svn   LogPrintf(LogCCP, "CCP Up event!!\n");
2751ae349f5Scvs2svn }
2761ae349f5Scvs2svn 
2771ae349f5Scvs2svn void
2781ae349f5Scvs2svn CcpOpen()
2791ae349f5Scvs2svn {
2801ae349f5Scvs2svn   int f;
2811ae349f5Scvs2svn 
2821ae349f5Scvs2svn   for (f = 0; f < NALGORITHMS; f++)
2831ae349f5Scvs2svn     if (Enabled(algorithm[f]->Conf)) {
2841ae349f5Scvs2svn       CcpFsm.open_mode = 0;
2851ae349f5Scvs2svn       FsmOpen(&CcpFsm);
2861ae349f5Scvs2svn       break;
2871ae349f5Scvs2svn     }
2881ae349f5Scvs2svn 
2891ae349f5Scvs2svn   if (f == NALGORITHMS)
2901ae349f5Scvs2svn     for (f = 0; f < NALGORITHMS; f++)
2911ae349f5Scvs2svn       if (Acceptable(algorithm[f]->Conf)) {
2921ae349f5Scvs2svn         CcpFsm.open_mode = OPEN_PASSIVE;
2931ae349f5Scvs2svn         FsmOpen(&CcpFsm);
2941ae349f5Scvs2svn         break;
2951ae349f5Scvs2svn       }
2961ae349f5Scvs2svn }
2971ae349f5Scvs2svn 
2981ae349f5Scvs2svn static void
2991ae349f5Scvs2svn CcpDecodeConfig(u_char *cp, int plen, int mode_type)
3001ae349f5Scvs2svn {
3011ae349f5Scvs2svn   int type, length;
3021ae349f5Scvs2svn   int f;
3031ae349f5Scvs2svn 
3041ae349f5Scvs2svn   ackp = AckBuff;
3051ae349f5Scvs2svn   nakp = NakBuff;
3061ae349f5Scvs2svn   rejp = RejBuff;
3071ae349f5Scvs2svn 
3081ae349f5Scvs2svn   while (plen >= sizeof(struct fsmconfig)) {
3091ae349f5Scvs2svn     type = *cp;
3101ae349f5Scvs2svn     length = cp[1];
3111ae349f5Scvs2svn     if (type < NCFTYPES)
3121ae349f5Scvs2svn       LogPrintf(LogCCP, " %s[%d]\n", cftypes[type], length);
3131ae349f5Scvs2svn     else
3141ae349f5Scvs2svn       LogPrintf(LogCCP, " ???[%d]\n", length);
3151ae349f5Scvs2svn 
3161ae349f5Scvs2svn     for (f = NALGORITHMS-1; f > -1; f--)
3171ae349f5Scvs2svn       if (algorithm[f]->id == type)
3181ae349f5Scvs2svn         break;
3191ae349f5Scvs2svn 
3201ae349f5Scvs2svn     if (f == -1) {
3211ae349f5Scvs2svn       /* Don't understand that :-( */
3221ae349f5Scvs2svn       if (mode_type == MODE_REQ) {
3231ae349f5Scvs2svn         CcpInfo.my_reject |= (1 << type);
3241ae349f5Scvs2svn         memcpy(rejp, cp, length);
3251ae349f5Scvs2svn         rejp += length;
3261ae349f5Scvs2svn       }
3271ae349f5Scvs2svn     } else {
3281ae349f5Scvs2svn       struct lcp_opt o;
3291ae349f5Scvs2svn 
3301ae349f5Scvs2svn       switch (mode_type) {
3311ae349f5Scvs2svn       case MODE_REQ:
332247ab36dSBrian Somers 	if (Acceptable(algorithm[f]->Conf) && CcpInfo.in_algorithm == -1) {
3331ae349f5Scvs2svn 	  memcpy(&o, cp, length);
3341ae349f5Scvs2svn           switch ((*algorithm[f]->i.Set)(&o)) {
3351ae349f5Scvs2svn           case MODE_REJ:
3361ae349f5Scvs2svn 	    memcpy(rejp, &o, o.len);
3371ae349f5Scvs2svn 	    rejp += o.len;
3381ae349f5Scvs2svn             break;
3391ae349f5Scvs2svn           case MODE_NAK:
3401ae349f5Scvs2svn 	    memcpy(nakp, &o, o.len);
3411ae349f5Scvs2svn 	    nakp += o.len;
3421ae349f5Scvs2svn             break;
3431ae349f5Scvs2svn           case MODE_ACK:
3441ae349f5Scvs2svn 	    memcpy(ackp, cp, length);
3451ae349f5Scvs2svn 	    ackp += length;
3461ae349f5Scvs2svn 	    CcpInfo.his_proto = type;
347247ab36dSBrian Somers             CcpInfo.in_algorithm = f;		/* This one'll do ! */
3481ae349f5Scvs2svn             break;
3491ae349f5Scvs2svn           }
3501ae349f5Scvs2svn 	} else {
3511ae349f5Scvs2svn 	  memcpy(rejp, cp, length);
3521ae349f5Scvs2svn 	  rejp += length;
3531ae349f5Scvs2svn 	}
3541ae349f5Scvs2svn 	break;
3551ae349f5Scvs2svn       case MODE_NAK:
3561ae349f5Scvs2svn 	memcpy(&o, cp, length);
3571ae349f5Scvs2svn         if ((*algorithm[f]->o.Set)(&o) == MODE_ACK)
3581ae349f5Scvs2svn           CcpInfo.my_proto = algorithm[f]->id;
3591ae349f5Scvs2svn         else {
3601ae349f5Scvs2svn 	  CcpInfo.his_reject |= (1 << type);
3611ae349f5Scvs2svn 	  CcpInfo.my_proto = -1;
3621ae349f5Scvs2svn         }
3631ae349f5Scvs2svn         break;
3641ae349f5Scvs2svn       case MODE_REJ:
3651ae349f5Scvs2svn 	CcpInfo.his_reject |= (1 << type);
3661ae349f5Scvs2svn 	CcpInfo.my_proto = -1;
3671ae349f5Scvs2svn 	break;
3681ae349f5Scvs2svn       }
3691ae349f5Scvs2svn     }
3701ae349f5Scvs2svn 
3711ae349f5Scvs2svn     plen -= length;
3721ae349f5Scvs2svn     cp += length;
3731ae349f5Scvs2svn   }
3741ae349f5Scvs2svn 
3751ae349f5Scvs2svn   if (rejp != RejBuff) {
3761ae349f5Scvs2svn     ackp = AckBuff;	/* let's not send both ! */
377247ab36dSBrian Somers     if (!CcpInfo.in_init) {
3781ae349f5Scvs2svn       CcpInfo.his_proto = -1;
379247ab36dSBrian Somers       CcpInfo.in_algorithm = -1;
380247ab36dSBrian Somers     }
3811ae349f5Scvs2svn   }
3821ae349f5Scvs2svn }
3831ae349f5Scvs2svn 
3841ae349f5Scvs2svn void
3851ae349f5Scvs2svn CcpInput(struct mbuf *bp)
3861ae349f5Scvs2svn {
3871ae349f5Scvs2svn   if (phase == PHASE_NETWORK)
3881ae349f5Scvs2svn     FsmInput(&CcpFsm, bp);
3891ae349f5Scvs2svn   else {
3901ae349f5Scvs2svn     if (phase > PHASE_NETWORK)
3911ae349f5Scvs2svn       LogPrintf(LogCCP, "Error: Unexpected CCP in phase %d\n", phase);
3921ae349f5Scvs2svn     pfree(bp);
3931ae349f5Scvs2svn   }
3941ae349f5Scvs2svn }
3951ae349f5Scvs2svn 
3961ae349f5Scvs2svn void
3971ae349f5Scvs2svn CcpResetInput(u_char id)
3981ae349f5Scvs2svn {
3991ae349f5Scvs2svn   if (CcpInfo.reset_sent != -1) {
4001ae349f5Scvs2svn     if (id != CcpInfo.reset_sent) {
4011ae349f5Scvs2svn       LogPrintf(LogWARN, "CCP: Incorrect ResetAck (id %d, not %d) ignored\n",
4021ae349f5Scvs2svn                 id, CcpInfo.reset_sent);
4031ae349f5Scvs2svn       return;
4041ae349f5Scvs2svn     }
4051ae349f5Scvs2svn     /* Whaddaya know - a correct reset ack */
4061ae349f5Scvs2svn   } else if (id == CcpInfo.last_reset)
4071ae349f5Scvs2svn     LogPrintf(LogCCP, "Duplicate ResetAck (resetting again)\n");
4081ae349f5Scvs2svn   else {
4091ae349f5Scvs2svn     LogPrintf(LogWARN, "CCP: Unexpected ResetAck (id %d) ignored\n", id);
4101ae349f5Scvs2svn     return;
4111ae349f5Scvs2svn   }
4121ae349f5Scvs2svn 
4131ae349f5Scvs2svn   CcpInfo.last_reset = CcpInfo.reset_sent;
4141ae349f5Scvs2svn   CcpInfo.reset_sent = -1;
415247ab36dSBrian Somers   if (CcpInfo.in_init)
416247ab36dSBrian Somers     (*algorithm[CcpInfo.in_algorithm]->i.Reset)();
4171ae349f5Scvs2svn }
4181ae349f5Scvs2svn 
4191ae349f5Scvs2svn int
42063b73463SBrian Somers CcpOutput(struct physical *physical, int pri, u_short proto, struct mbuf *m)
4211ae349f5Scvs2svn {
422247ab36dSBrian Somers   if (CcpInfo.out_init)
423247ab36dSBrian Somers     return (*algorithm[CcpInfo.out_algorithm]->o.Write)(physical, pri, proto, m);
4241ae349f5Scvs2svn   return 0;
4251ae349f5Scvs2svn }
4261ae349f5Scvs2svn 
4271ae349f5Scvs2svn struct mbuf *
4281ae349f5Scvs2svn CompdInput(u_short *proto, struct mbuf *m)
4291ae349f5Scvs2svn {
4301ae349f5Scvs2svn   if (CcpInfo.reset_sent != -1) {
4311ae349f5Scvs2svn     /* Send another REQ and put the packet in the bit bucket */
4321ae349f5Scvs2svn     LogPrintf(LogCCP, "ReSendResetReq(%d)\n", CcpInfo.reset_sent);
4331ae349f5Scvs2svn     FsmOutput(&CcpFsm, CODE_RESETREQ, CcpInfo.reset_sent, NULL, 0);
4341ae349f5Scvs2svn     pfree(m);
435247ab36dSBrian Somers   } else if (CcpInfo.in_init)
436247ab36dSBrian Somers     return (*algorithm[CcpInfo.in_algorithm]->i.Read)(proto, m);
4371ae349f5Scvs2svn   return NULL;
4381ae349f5Scvs2svn }
4391ae349f5Scvs2svn 
4401ae349f5Scvs2svn void
4411ae349f5Scvs2svn CcpDictSetup(u_short proto, struct mbuf *m)
4421ae349f5Scvs2svn {
443247ab36dSBrian Somers   if (CcpInfo.in_init)
444247ab36dSBrian Somers     (*algorithm[CcpInfo.in_algorithm]->i.DictSetup)(proto, m);
4451ae349f5Scvs2svn }
446