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