1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * ccp.c - PPP Compression Control Protocol. 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * Copyright (c) 2000 by Sun Microsystems, Inc. 5*7c478bd9Sstevel@tonic-gate * All rights reserved. 6*7c478bd9Sstevel@tonic-gate * 7*7c478bd9Sstevel@tonic-gate * Copyright (c) 1994 The Australian National University. 8*7c478bd9Sstevel@tonic-gate * All rights reserved. 9*7c478bd9Sstevel@tonic-gate * 10*7c478bd9Sstevel@tonic-gate * Permission to use, copy, modify, and distribute this software and its 11*7c478bd9Sstevel@tonic-gate * documentation is hereby granted, provided that the above copyright 12*7c478bd9Sstevel@tonic-gate * notice appears in all copies. This software is provided without any 13*7c478bd9Sstevel@tonic-gate * warranty, express or implied. The Australian National University 14*7c478bd9Sstevel@tonic-gate * makes no representations about the suitability of this software for 15*7c478bd9Sstevel@tonic-gate * any purpose. 16*7c478bd9Sstevel@tonic-gate * 17*7c478bd9Sstevel@tonic-gate * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY 18*7c478bd9Sstevel@tonic-gate * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 19*7c478bd9Sstevel@tonic-gate * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 20*7c478bd9Sstevel@tonic-gate * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY 21*7c478bd9Sstevel@tonic-gate * OF SUCH DAMAGE. 22*7c478bd9Sstevel@tonic-gate * 23*7c478bd9Sstevel@tonic-gate * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, 24*7c478bd9Sstevel@tonic-gate * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 25*7c478bd9Sstevel@tonic-gate * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 26*7c478bd9Sstevel@tonic-gate * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO 27*7c478bd9Sstevel@tonic-gate * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, 28*7c478bd9Sstevel@tonic-gate * OR MODIFICATIONS. 29*7c478bd9Sstevel@tonic-gate */ 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*7c478bd9Sstevel@tonic-gate #define RCSID "$Id: ccp.c,v 1.30 2000/04/15 01:27:11 masputra Exp $" 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 35*7c478bd9Sstevel@tonic-gate #include <string.h> 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate #include "pppd.h" 38*7c478bd9Sstevel@tonic-gate #include "fsm.h" 39*7c478bd9Sstevel@tonic-gate #include "ccp.h" 40*7c478bd9Sstevel@tonic-gate #include <net/ppp-comp.h> 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate #if !defined(lint) && !defined(_lint) 43*7c478bd9Sstevel@tonic-gate static const char rcsid[] = RCSID; 44*7c478bd9Sstevel@tonic-gate #endif 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate /* 47*7c478bd9Sstevel@tonic-gate * Command-line options. 48*7c478bd9Sstevel@tonic-gate */ 49*7c478bd9Sstevel@tonic-gate static int setbsdcomp __P((char **, option_t *)); 50*7c478bd9Sstevel@tonic-gate static int setdeflate __P((char **, option_t *)); 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate static option_t ccp_option_list[] = { 53*7c478bd9Sstevel@tonic-gate { "noccp", o_bool, &ccp_protent.enabled_flag, 54*7c478bd9Sstevel@tonic-gate "Disable CCP negotiation" }, 55*7c478bd9Sstevel@tonic-gate { "-ccp", o_bool, &ccp_protent.enabled_flag, 56*7c478bd9Sstevel@tonic-gate "Disable CCP negotiation" }, 57*7c478bd9Sstevel@tonic-gate { "bsdcomp", o_special, (void *)setbsdcomp, 58*7c478bd9Sstevel@tonic-gate "Request BSD-Compress packet compression" }, 59*7c478bd9Sstevel@tonic-gate { "nobsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, 60*7c478bd9Sstevel@tonic-gate "don't allow BSD-Compress", OPT_A2COPY, 61*7c478bd9Sstevel@tonic-gate &ccp_allowoptions[0].bsd_compress }, 62*7c478bd9Sstevel@tonic-gate { "-bsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, 63*7c478bd9Sstevel@tonic-gate "don't allow BSD-Compress", OPT_A2COPY, 64*7c478bd9Sstevel@tonic-gate &ccp_allowoptions[0].bsd_compress }, 65*7c478bd9Sstevel@tonic-gate { "deflate", o_special, (void *)setdeflate, 66*7c478bd9Sstevel@tonic-gate "request Deflate compression" }, 67*7c478bd9Sstevel@tonic-gate { "nodeflate", o_bool, &ccp_wantoptions[0].deflate, 68*7c478bd9Sstevel@tonic-gate "don't allow Deflate compression", OPT_A2COPY, 69*7c478bd9Sstevel@tonic-gate &ccp_allowoptions[0].deflate }, 70*7c478bd9Sstevel@tonic-gate { "-deflate", o_bool, &ccp_wantoptions[0].deflate, 71*7c478bd9Sstevel@tonic-gate "don't allow Deflate compression", OPT_A2COPY, 72*7c478bd9Sstevel@tonic-gate &ccp_allowoptions[0].deflate }, 73*7c478bd9Sstevel@tonic-gate { "nodeflatedraft", o_bool, &ccp_wantoptions[0].deflate_draft, 74*7c478bd9Sstevel@tonic-gate "don't use draft deflate #", OPT_A2COPY, 75*7c478bd9Sstevel@tonic-gate &ccp_allowoptions[0].deflate_draft }, 76*7c478bd9Sstevel@tonic-gate { "predictor1", o_bool, &ccp_wantoptions[0].predictor_1, 77*7c478bd9Sstevel@tonic-gate "request Predictor-1", 1, &ccp_allowoptions[0].predictor_1 }, 78*7c478bd9Sstevel@tonic-gate { "nopredictor1", o_bool, &ccp_wantoptions[0].predictor_1, 79*7c478bd9Sstevel@tonic-gate "don't allow Predictor-1", OPT_A2COPY, 80*7c478bd9Sstevel@tonic-gate &ccp_allowoptions[0].predictor_1 }, 81*7c478bd9Sstevel@tonic-gate { "-predictor1", o_bool, &ccp_wantoptions[0].predictor_1, 82*7c478bd9Sstevel@tonic-gate "don't allow Predictor-1", OPT_A2COPY, 83*7c478bd9Sstevel@tonic-gate &ccp_allowoptions[0].predictor_1 }, 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate { NULL } 86*7c478bd9Sstevel@tonic-gate }; 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate /* 89*7c478bd9Sstevel@tonic-gate * Protocol entry points from main code. 90*7c478bd9Sstevel@tonic-gate */ 91*7c478bd9Sstevel@tonic-gate static void ccp_init __P((int unit)); 92*7c478bd9Sstevel@tonic-gate static void ccp_open __P((int unit)); 93*7c478bd9Sstevel@tonic-gate static void ccp_close __P((int unit, char *)); 94*7c478bd9Sstevel@tonic-gate static void ccp_lowerup __P((int unit)); 95*7c478bd9Sstevel@tonic-gate static void ccp_lowerdown __P((int)); 96*7c478bd9Sstevel@tonic-gate static void ccp_input __P((int unit, u_char *pkt, int len)); 97*7c478bd9Sstevel@tonic-gate static void ccp_protrej __P((int unit)); 98*7c478bd9Sstevel@tonic-gate static int ccp_printpkt __P((u_char *pkt, int len, 99*7c478bd9Sstevel@tonic-gate void (*printer) __P((void *, const char *, ...)), 100*7c478bd9Sstevel@tonic-gate void *arg)); 101*7c478bd9Sstevel@tonic-gate static void ccp_datainput __P((int unit, u_char *pkt, int len)); 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate struct protent ccp_protent = { 104*7c478bd9Sstevel@tonic-gate PPP_CCP, 105*7c478bd9Sstevel@tonic-gate ccp_init, 106*7c478bd9Sstevel@tonic-gate ccp_input, 107*7c478bd9Sstevel@tonic-gate ccp_protrej, 108*7c478bd9Sstevel@tonic-gate ccp_lowerup, 109*7c478bd9Sstevel@tonic-gate ccp_lowerdown, 110*7c478bd9Sstevel@tonic-gate ccp_open, 111*7c478bd9Sstevel@tonic-gate ccp_close, 112*7c478bd9Sstevel@tonic-gate ccp_printpkt, 113*7c478bd9Sstevel@tonic-gate ccp_datainput, 114*7c478bd9Sstevel@tonic-gate 1, 115*7c478bd9Sstevel@tonic-gate "CCP", 116*7c478bd9Sstevel@tonic-gate "Compressed", 117*7c478bd9Sstevel@tonic-gate ccp_option_list, 118*7c478bd9Sstevel@tonic-gate NULL, 119*7c478bd9Sstevel@tonic-gate NULL, 120*7c478bd9Sstevel@tonic-gate NULL 121*7c478bd9Sstevel@tonic-gate }; 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate fsm ccp_fsm[NUM_PPP]; 124*7c478bd9Sstevel@tonic-gate ccp_options ccp_wantoptions[NUM_PPP]; /* what to request the peer to use */ 125*7c478bd9Sstevel@tonic-gate ccp_options ccp_gotoptions[NUM_PPP]; /* what the peer agreed to do */ 126*7c478bd9Sstevel@tonic-gate ccp_options ccp_allowoptions[NUM_PPP]; /* what we'll agree to do */ 127*7c478bd9Sstevel@tonic-gate ccp_options ccp_hisoptions[NUM_PPP]; /* what we agreed to do */ 128*7c478bd9Sstevel@tonic-gate 129*7c478bd9Sstevel@tonic-gate /* 130*7c478bd9Sstevel@tonic-gate * Callbacks for fsm code. 131*7c478bd9Sstevel@tonic-gate */ 132*7c478bd9Sstevel@tonic-gate static void ccp_resetci __P((fsm *)); 133*7c478bd9Sstevel@tonic-gate static int ccp_cilen __P((fsm *)); 134*7c478bd9Sstevel@tonic-gate static void ccp_addci __P((fsm *, u_char *, int *)); 135*7c478bd9Sstevel@tonic-gate static int ccp_ackci __P((fsm *, u_char *, int)); 136*7c478bd9Sstevel@tonic-gate static int ccp_nakci __P((fsm *, u_char *, int)); 137*7c478bd9Sstevel@tonic-gate static int ccp_rejci __P((fsm *, u_char *, int)); 138*7c478bd9Sstevel@tonic-gate static int ccp_reqci __P((fsm *, u_char *, int *, int)); 139*7c478bd9Sstevel@tonic-gate static void ccp_up __P((fsm *)); 140*7c478bd9Sstevel@tonic-gate static void ccp_down __P((fsm *)); 141*7c478bd9Sstevel@tonic-gate static int ccp_extcode __P((fsm *, int, int, u_char *, int)); 142*7c478bd9Sstevel@tonic-gate static int ccp_codereject __P((fsm *p, int code, int id, u_char *inp, 143*7c478bd9Sstevel@tonic-gate int len)); 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate static fsm_callbacks ccp_callbacks = { 146*7c478bd9Sstevel@tonic-gate ccp_resetci, /* Reset our Configuration Information */ 147*7c478bd9Sstevel@tonic-gate ccp_cilen, /* Length of our Configuration Information */ 148*7c478bd9Sstevel@tonic-gate ccp_addci, /* Add our Configuration Information */ 149*7c478bd9Sstevel@tonic-gate ccp_ackci, /* ACK our Configuration Information */ 150*7c478bd9Sstevel@tonic-gate ccp_nakci, /* NAK our Configuration Information */ 151*7c478bd9Sstevel@tonic-gate ccp_rejci, /* Reject our Configuration Information */ 152*7c478bd9Sstevel@tonic-gate ccp_reqci, /* Request peer's Configuration Information */ 153*7c478bd9Sstevel@tonic-gate ccp_up, /* Called when fsm reaches OPENED state */ 154*7c478bd9Sstevel@tonic-gate ccp_down, /* Called when fsm leaves OPENED state */ 155*7c478bd9Sstevel@tonic-gate NULL, /* Called when we want the lower layer up */ 156*7c478bd9Sstevel@tonic-gate NULL, /* Called when we want the lower layer down */ 157*7c478bd9Sstevel@tonic-gate NULL, /* Retransmission is necessary */ 158*7c478bd9Sstevel@tonic-gate ccp_extcode, /* Called to handle LCP-specific codes */ 159*7c478bd9Sstevel@tonic-gate "CCP", /* String name of protocol */ 160*7c478bd9Sstevel@tonic-gate ccp_codereject, /* Peer rejected a code number */ 161*7c478bd9Sstevel@tonic-gate }; 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate /* 164*7c478bd9Sstevel@tonic-gate * Local statics. 165*7c478bd9Sstevel@tonic-gate */ 166*7c478bd9Sstevel@tonic-gate static void ccp_rack_timeout __P((void *)); 167*7c478bd9Sstevel@tonic-gate static char * method_name __P((ccp_options *, ccp_options *)); 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate /* 170*7c478bd9Sstevel@tonic-gate * Do we want / did we get any compression? 171*7c478bd9Sstevel@tonic-gate */ 172*7c478bd9Sstevel@tonic-gate #define ANY_COMPRESS(opt) ((opt).deflate || (opt).bsd_compress \ 173*7c478bd9Sstevel@tonic-gate || (opt).predictor_1 || (opt).predictor_2) 174*7c478bd9Sstevel@tonic-gate 175*7c478bd9Sstevel@tonic-gate /* 176*7c478bd9Sstevel@tonic-gate * Local state (mainly for handling reset-reqs and reset-acks). 177*7c478bd9Sstevel@tonic-gate */ 178*7c478bd9Sstevel@tonic-gate static int ccp_localstate[NUM_PPP]; 179*7c478bd9Sstevel@tonic-gate #define RACK_PENDING 0x0001 /* waiting for reset-ack */ 180*7c478bd9Sstevel@tonic-gate #define RREQ_REPEAT 0x0002 /* send another reset-req if no reset-ack */ 181*7c478bd9Sstevel@tonic-gate #define RREQ_REJECTED 0x0004 /* peer code-rejected reset-request */ 182*7c478bd9Sstevel@tonic-gate #define RACK_REJECTED 0x0008 /* peer code-rejected reset-ack */ 183*7c478bd9Sstevel@tonic-gate #define RREQ_IGNORED 0x0010 /* peer just ignored reset-request */ 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate #define RACKTIMEOUT 1 /* time in seconds between Reset-Requests */ 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate static int all_rejected[NUM_PPP]; /* we rejected all peer's options */ 188*7c478bd9Sstevel@tonic-gate 189*7c478bd9Sstevel@tonic-gate #ifdef COMP_TUNE 190*7c478bd9Sstevel@tonic-gate static int deflate_tune = -1; /* compression effort level for deflate */ 191*7c478bd9Sstevel@tonic-gate #endif 192*7c478bd9Sstevel@tonic-gate static int deflate_rmax = DEFLATE_MAX_SIZE; /* max rbits */ 193*7c478bd9Sstevel@tonic-gate static int deflate_amax = DEFLATE_MAX_SIZE; /* max abits */ 194*7c478bd9Sstevel@tonic-gate 195*7c478bd9Sstevel@tonic-gate /* 196*7c478bd9Sstevel@tonic-gate * Option parsing. 197*7c478bd9Sstevel@tonic-gate */ 198*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 199*7c478bd9Sstevel@tonic-gate static int 200*7c478bd9Sstevel@tonic-gate setbsdcomp(argv, opt) 201*7c478bd9Sstevel@tonic-gate char **argv; 202*7c478bd9Sstevel@tonic-gate option_t *opt; 203*7c478bd9Sstevel@tonic-gate { 204*7c478bd9Sstevel@tonic-gate int rbits, abits; 205*7c478bd9Sstevel@tonic-gate char *str, *endp; 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate str = *argv; 208*7c478bd9Sstevel@tonic-gate abits = rbits = strtol(str, &endp, 0); 209*7c478bd9Sstevel@tonic-gate if (endp != str && *endp == ',') { 210*7c478bd9Sstevel@tonic-gate str = endp + 1; 211*7c478bd9Sstevel@tonic-gate abits = strtol(str, &endp, 0); 212*7c478bd9Sstevel@tonic-gate } 213*7c478bd9Sstevel@tonic-gate if (*endp != '\0' || endp == str) { 214*7c478bd9Sstevel@tonic-gate option_error("invalid parameter '%s' for bsdcomp option", *argv); 215*7c478bd9Sstevel@tonic-gate return 0; 216*7c478bd9Sstevel@tonic-gate } 217*7c478bd9Sstevel@tonic-gate if ((rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS)) 218*7c478bd9Sstevel@tonic-gate || (abits != 0 && (abits < BSD_MIN_BITS || abits > BSD_MAX_BITS))) { 219*7c478bd9Sstevel@tonic-gate option_error("bsdcomp option values must be 0 or %d .. %d", 220*7c478bd9Sstevel@tonic-gate BSD_MIN_BITS, BSD_MAX_BITS); 221*7c478bd9Sstevel@tonic-gate return 0; 222*7c478bd9Sstevel@tonic-gate } 223*7c478bd9Sstevel@tonic-gate if (rbits > 0) { 224*7c478bd9Sstevel@tonic-gate ccp_wantoptions[0].bsd_compress = 1; 225*7c478bd9Sstevel@tonic-gate ccp_wantoptions[0].bsd_bits = rbits; 226*7c478bd9Sstevel@tonic-gate } else 227*7c478bd9Sstevel@tonic-gate ccp_wantoptions[0].bsd_compress = 0; 228*7c478bd9Sstevel@tonic-gate if (abits > 0) { 229*7c478bd9Sstevel@tonic-gate ccp_allowoptions[0].bsd_compress = 1; 230*7c478bd9Sstevel@tonic-gate ccp_allowoptions[0].bsd_bits = abits; 231*7c478bd9Sstevel@tonic-gate } else 232*7c478bd9Sstevel@tonic-gate ccp_allowoptions[0].bsd_compress = 0; 233*7c478bd9Sstevel@tonic-gate return 1; 234*7c478bd9Sstevel@tonic-gate } 235*7c478bd9Sstevel@tonic-gate 236*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 237*7c478bd9Sstevel@tonic-gate static int 238*7c478bd9Sstevel@tonic-gate setdeflate(argv, opt) 239*7c478bd9Sstevel@tonic-gate char **argv; 240*7c478bd9Sstevel@tonic-gate option_t *opt; 241*7c478bd9Sstevel@tonic-gate { 242*7c478bd9Sstevel@tonic-gate int rbits, abits, def_rmax, def_amax; 243*7c478bd9Sstevel@tonic-gate char *str, *endp; 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate str = endp = *argv; 246*7c478bd9Sstevel@tonic-gate if (*str == ',') 247*7c478bd9Sstevel@tonic-gate abits = rbits = -1; 248*7c478bd9Sstevel@tonic-gate else 249*7c478bd9Sstevel@tonic-gate abits = rbits = strtol(str, &endp, 0); 250*7c478bd9Sstevel@tonic-gate if (*endp == ',') { 251*7c478bd9Sstevel@tonic-gate str = ++endp; 252*7c478bd9Sstevel@tonic-gate if (*str == ',') 253*7c478bd9Sstevel@tonic-gate abits = rbits; 254*7c478bd9Sstevel@tonic-gate else 255*7c478bd9Sstevel@tonic-gate abits = strtol(str, &endp, 0); 256*7c478bd9Sstevel@tonic-gate } 257*7c478bd9Sstevel@tonic-gate #ifdef COMP_TUNE 258*7c478bd9Sstevel@tonic-gate if (*endp == ',' && privileged_option) { 259*7c478bd9Sstevel@tonic-gate str = ++endp; 260*7c478bd9Sstevel@tonic-gate deflate_tune = strtol(str, &endp, 0); 261*7c478bd9Sstevel@tonic-gate } 262*7c478bd9Sstevel@tonic-gate #endif 263*7c478bd9Sstevel@tonic-gate if (*endp != '\0' || endp == str) { 264*7c478bd9Sstevel@tonic-gate option_error("invalid parameter '%s' for deflate option", *argv); 265*7c478bd9Sstevel@tonic-gate return 0; 266*7c478bd9Sstevel@tonic-gate } 267*7c478bd9Sstevel@tonic-gate if (privileged_option) { 268*7c478bd9Sstevel@tonic-gate def_rmax = def_amax = DEFLATE_MAX_SIZE; 269*7c478bd9Sstevel@tonic-gate } else { 270*7c478bd9Sstevel@tonic-gate def_rmax = deflate_rmax; 271*7c478bd9Sstevel@tonic-gate def_amax = deflate_amax; 272*7c478bd9Sstevel@tonic-gate } 273*7c478bd9Sstevel@tonic-gate if (rbits < 0) 274*7c478bd9Sstevel@tonic-gate rbits = def_rmax; 275*7c478bd9Sstevel@tonic-gate if (abits < 0) 276*7c478bd9Sstevel@tonic-gate abits = def_amax; 277*7c478bd9Sstevel@tonic-gate if ((rbits != 0 && (rbits <= DEFLATE_MIN_SIZE || rbits > def_rmax)) 278*7c478bd9Sstevel@tonic-gate || (abits != 0 && (abits <= DEFLATE_MIN_SIZE || abits > def_amax))) { 279*7c478bd9Sstevel@tonic-gate option_error("deflate option values must be 0 or {%d,%d} .. {%d,%d}", 280*7c478bd9Sstevel@tonic-gate DEFLATE_MIN_SIZE+1, DEFLATE_MIN_SIZE+1, 281*7c478bd9Sstevel@tonic-gate def_rmax, def_amax); 282*7c478bd9Sstevel@tonic-gate return 0; 283*7c478bd9Sstevel@tonic-gate } 284*7c478bd9Sstevel@tonic-gate if (privileged_option) { 285*7c478bd9Sstevel@tonic-gate deflate_rmax = rbits; 286*7c478bd9Sstevel@tonic-gate deflate_amax = abits; 287*7c478bd9Sstevel@tonic-gate } 288*7c478bd9Sstevel@tonic-gate if (rbits > 0) { 289*7c478bd9Sstevel@tonic-gate ccp_wantoptions[0].deflate = 1; 290*7c478bd9Sstevel@tonic-gate ccp_wantoptions[0].deflate_size = rbits; 291*7c478bd9Sstevel@tonic-gate } else 292*7c478bd9Sstevel@tonic-gate ccp_wantoptions[0].deflate = 0; 293*7c478bd9Sstevel@tonic-gate if (abits > 0) { 294*7c478bd9Sstevel@tonic-gate ccp_allowoptions[0].deflate = 1; 295*7c478bd9Sstevel@tonic-gate ccp_allowoptions[0].deflate_size = abits; 296*7c478bd9Sstevel@tonic-gate } else 297*7c478bd9Sstevel@tonic-gate ccp_allowoptions[0].deflate = 0; 298*7c478bd9Sstevel@tonic-gate return 1; 299*7c478bd9Sstevel@tonic-gate } 300*7c478bd9Sstevel@tonic-gate 301*7c478bd9Sstevel@tonic-gate 302*7c478bd9Sstevel@tonic-gate /* 303*7c478bd9Sstevel@tonic-gate * ccp_init - initialize CCP. 304*7c478bd9Sstevel@tonic-gate */ 305*7c478bd9Sstevel@tonic-gate static void 306*7c478bd9Sstevel@tonic-gate ccp_init(unit) 307*7c478bd9Sstevel@tonic-gate int unit; 308*7c478bd9Sstevel@tonic-gate { 309*7c478bd9Sstevel@tonic-gate fsm *f = &ccp_fsm[unit]; 310*7c478bd9Sstevel@tonic-gate 311*7c478bd9Sstevel@tonic-gate f->unit = unit; 312*7c478bd9Sstevel@tonic-gate f->protocol = PPP_CCP; 313*7c478bd9Sstevel@tonic-gate f->callbacks = &ccp_callbacks; 314*7c478bd9Sstevel@tonic-gate fsm_init(f); 315*7c478bd9Sstevel@tonic-gate f->flags |= OPT_RESTART; 316*7c478bd9Sstevel@tonic-gate 317*7c478bd9Sstevel@tonic-gate BZERO(&ccp_wantoptions[unit], sizeof(ccp_options)); 318*7c478bd9Sstevel@tonic-gate BZERO(&ccp_gotoptions[unit], sizeof(ccp_options)); 319*7c478bd9Sstevel@tonic-gate BZERO(&ccp_allowoptions[unit], sizeof(ccp_options)); 320*7c478bd9Sstevel@tonic-gate BZERO(&ccp_hisoptions[unit], sizeof(ccp_options)); 321*7c478bd9Sstevel@tonic-gate 322*7c478bd9Sstevel@tonic-gate ccp_wantoptions[0].deflate = 1; 323*7c478bd9Sstevel@tonic-gate ccp_wantoptions[0].deflate_size = DEFLATE_MAX_SIZE; 324*7c478bd9Sstevel@tonic-gate ccp_wantoptions[0].deflate_correct = 1; 325*7c478bd9Sstevel@tonic-gate ccp_wantoptions[0].deflate_draft = 1; 326*7c478bd9Sstevel@tonic-gate ccp_allowoptions[0].deflate = 1; 327*7c478bd9Sstevel@tonic-gate ccp_allowoptions[0].deflate_size = DEFLATE_MAX_SIZE; 328*7c478bd9Sstevel@tonic-gate ccp_allowoptions[0].deflate_correct = 1; 329*7c478bd9Sstevel@tonic-gate ccp_allowoptions[0].deflate_draft = 1; 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate ccp_wantoptions[0].bsd_compress = 1; 332*7c478bd9Sstevel@tonic-gate ccp_wantoptions[0].bsd_bits = BSD_MAX_BITS; 333*7c478bd9Sstevel@tonic-gate ccp_allowoptions[0].bsd_compress = 1; 334*7c478bd9Sstevel@tonic-gate ccp_allowoptions[0].bsd_bits = BSD_MAX_BITS; 335*7c478bd9Sstevel@tonic-gate 336*7c478bd9Sstevel@tonic-gate ccp_allowoptions[0].predictor_1 = 1; 337*7c478bd9Sstevel@tonic-gate } 338*7c478bd9Sstevel@tonic-gate 339*7c478bd9Sstevel@tonic-gate /* 340*7c478bd9Sstevel@tonic-gate * ccp_open - CCP is allowed to come up. 341*7c478bd9Sstevel@tonic-gate */ 342*7c478bd9Sstevel@tonic-gate static void 343*7c478bd9Sstevel@tonic-gate ccp_open(unit) 344*7c478bd9Sstevel@tonic-gate int unit; 345*7c478bd9Sstevel@tonic-gate { 346*7c478bd9Sstevel@tonic-gate fsm *f = &ccp_fsm[unit]; 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate /* 349*7c478bd9Sstevel@tonic-gate * If we haven't gone open yet (first time through), then go open 350*7c478bd9Sstevel@tonic-gate * but not up. Otherwise, skip this to allow reopen to reset the 351*7c478bd9Sstevel@tonic-gate * compressor. 352*7c478bd9Sstevel@tonic-gate */ 353*7c478bd9Sstevel@tonic-gate if (f->state != OPENED) 354*7c478bd9Sstevel@tonic-gate ccp_flags_set(unit, 1, 0); 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate /* 357*7c478bd9Sstevel@tonic-gate * Find out which compressors the kernel supports before 358*7c478bd9Sstevel@tonic-gate * deciding whether to open in silent mode. 359*7c478bd9Sstevel@tonic-gate */ 360*7c478bd9Sstevel@tonic-gate ccp_resetci(f); 361*7c478bd9Sstevel@tonic-gate if (!ANY_COMPRESS(ccp_gotoptions[unit])) 362*7c478bd9Sstevel@tonic-gate f->flags |= OPT_SILENT; 363*7c478bd9Sstevel@tonic-gate 364*7c478bd9Sstevel@tonic-gate fsm_open(f); 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate /* 368*7c478bd9Sstevel@tonic-gate * ccp_close - Terminate CCP. 369*7c478bd9Sstevel@tonic-gate */ 370*7c478bd9Sstevel@tonic-gate static void 371*7c478bd9Sstevel@tonic-gate ccp_close(unit, reason) 372*7c478bd9Sstevel@tonic-gate int unit; 373*7c478bd9Sstevel@tonic-gate char *reason; 374*7c478bd9Sstevel@tonic-gate { 375*7c478bd9Sstevel@tonic-gate ccp_flags_set(unit, 0, 0); 376*7c478bd9Sstevel@tonic-gate fsm_close(&ccp_fsm[unit], reason); 377*7c478bd9Sstevel@tonic-gate } 378*7c478bd9Sstevel@tonic-gate 379*7c478bd9Sstevel@tonic-gate /* 380*7c478bd9Sstevel@tonic-gate * ccp_lowerup - we may now transmit CCP packets. 381*7c478bd9Sstevel@tonic-gate */ 382*7c478bd9Sstevel@tonic-gate static void 383*7c478bd9Sstevel@tonic-gate ccp_lowerup(unit) 384*7c478bd9Sstevel@tonic-gate int unit; 385*7c478bd9Sstevel@tonic-gate { 386*7c478bd9Sstevel@tonic-gate fsm_lowerup(&ccp_fsm[unit]); 387*7c478bd9Sstevel@tonic-gate } 388*7c478bd9Sstevel@tonic-gate 389*7c478bd9Sstevel@tonic-gate /* 390*7c478bd9Sstevel@tonic-gate * ccp_lowerdown - we may not transmit CCP packets. 391*7c478bd9Sstevel@tonic-gate */ 392*7c478bd9Sstevel@tonic-gate static void 393*7c478bd9Sstevel@tonic-gate ccp_lowerdown(unit) 394*7c478bd9Sstevel@tonic-gate int unit; 395*7c478bd9Sstevel@tonic-gate { 396*7c478bd9Sstevel@tonic-gate fsm_lowerdown(&ccp_fsm[unit]); 397*7c478bd9Sstevel@tonic-gate } 398*7c478bd9Sstevel@tonic-gate 399*7c478bd9Sstevel@tonic-gate /* 400*7c478bd9Sstevel@tonic-gate * ccp_input - process a received CCP packet. 401*7c478bd9Sstevel@tonic-gate */ 402*7c478bd9Sstevel@tonic-gate static void 403*7c478bd9Sstevel@tonic-gate ccp_input(unit, p, len) 404*7c478bd9Sstevel@tonic-gate int unit; 405*7c478bd9Sstevel@tonic-gate u_char *p; 406*7c478bd9Sstevel@tonic-gate int len; 407*7c478bd9Sstevel@tonic-gate { 408*7c478bd9Sstevel@tonic-gate fsm *f = &ccp_fsm[unit]; 409*7c478bd9Sstevel@tonic-gate int oldstate; 410*7c478bd9Sstevel@tonic-gate 411*7c478bd9Sstevel@tonic-gate /* 412*7c478bd9Sstevel@tonic-gate * Check for a terminate-request so we can print a message. 413*7c478bd9Sstevel@tonic-gate */ 414*7c478bd9Sstevel@tonic-gate oldstate = f->state; 415*7c478bd9Sstevel@tonic-gate fsm_input(f, p, len); 416*7c478bd9Sstevel@tonic-gate if (oldstate == OPENED && p[0] == CODE_TERMREQ && f->state != OPENED) 417*7c478bd9Sstevel@tonic-gate notice("Compression disabled by peer."); 418*7c478bd9Sstevel@tonic-gate 419*7c478bd9Sstevel@tonic-gate /* 420*7c478bd9Sstevel@tonic-gate * If we get a terminate-ack and we're not asking for compression, 421*7c478bd9Sstevel@tonic-gate * close CCP. (Terminate-Request is handled by fsm_input() above.) 422*7c478bd9Sstevel@tonic-gate */ 423*7c478bd9Sstevel@tonic-gate if (oldstate == REQSENT && p[0] == CODE_TERMACK 424*7c478bd9Sstevel@tonic-gate && !ANY_COMPRESS(ccp_gotoptions[unit])) 425*7c478bd9Sstevel@tonic-gate ccp_close(unit, "No compression negotiated"); 426*7c478bd9Sstevel@tonic-gate } 427*7c478bd9Sstevel@tonic-gate 428*7c478bd9Sstevel@tonic-gate /* 429*7c478bd9Sstevel@tonic-gate * Handle a CCP-specific code. 430*7c478bd9Sstevel@tonic-gate */ 431*7c478bd9Sstevel@tonic-gate static int 432*7c478bd9Sstevel@tonic-gate ccp_extcode(f, code, id, p, len) 433*7c478bd9Sstevel@tonic-gate fsm *f; 434*7c478bd9Sstevel@tonic-gate int code, id; 435*7c478bd9Sstevel@tonic-gate u_char *p; 436*7c478bd9Sstevel@tonic-gate int len; 437*7c478bd9Sstevel@tonic-gate { 438*7c478bd9Sstevel@tonic-gate switch (code) { 439*7c478bd9Sstevel@tonic-gate case CCP_RESETREQ: 440*7c478bd9Sstevel@tonic-gate /* If not open, then silently ignore. */ 441*7c478bd9Sstevel@tonic-gate if (f->state != OPENED) 442*7c478bd9Sstevel@tonic-gate break; 443*7c478bd9Sstevel@tonic-gate /* send a reset-ack, which our transmitter module will see and 444*7c478bd9Sstevel@tonic-gate reset its compression state. */ 445*7c478bd9Sstevel@tonic-gate fsm_sdata(f, CCP_RESETACK, id, p, len); 446*7c478bd9Sstevel@tonic-gate break; 447*7c478bd9Sstevel@tonic-gate 448*7c478bd9Sstevel@tonic-gate case CCP_RESETACK: 449*7c478bd9Sstevel@tonic-gate /* 450*7c478bd9Sstevel@tonic-gate * Note that the compression module isn't picky about ID 451*7c478bd9Sstevel@tonic-gate * numbers and such. 452*7c478bd9Sstevel@tonic-gate */ 453*7c478bd9Sstevel@tonic-gate ccp_localstate[f->unit] &= ~RREQ_IGNORED & ~RREQ_REJECTED; 454*7c478bd9Sstevel@tonic-gate if ((ccp_localstate[f->unit] & RACK_PENDING) && id == f->reqid) { 455*7c478bd9Sstevel@tonic-gate ccp_localstate[f->unit] &= ~RACK_PENDING & ~RREQ_REPEAT; 456*7c478bd9Sstevel@tonic-gate UNTIMEOUT(ccp_rack_timeout, f); 457*7c478bd9Sstevel@tonic-gate } 458*7c478bd9Sstevel@tonic-gate break; 459*7c478bd9Sstevel@tonic-gate 460*7c478bd9Sstevel@tonic-gate default: 461*7c478bd9Sstevel@tonic-gate /* Tell fsm to send code reject */ 462*7c478bd9Sstevel@tonic-gate return (0); 463*7c478bd9Sstevel@tonic-gate } 464*7c478bd9Sstevel@tonic-gate 465*7c478bd9Sstevel@tonic-gate return (1); 466*7c478bd9Sstevel@tonic-gate } 467*7c478bd9Sstevel@tonic-gate 468*7c478bd9Sstevel@tonic-gate /* 469*7c478bd9Sstevel@tonic-gate * Handle Code-Reject for one of our extended codes by dropping back to 470*7c478bd9Sstevel@tonic-gate * reopen as mechanism to restart compression. 471*7c478bd9Sstevel@tonic-gate */ 472*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 473*7c478bd9Sstevel@tonic-gate static int 474*7c478bd9Sstevel@tonic-gate ccp_codereject(f, code, id, inp, len) 475*7c478bd9Sstevel@tonic-gate fsm *f; 476*7c478bd9Sstevel@tonic-gate int code, id; 477*7c478bd9Sstevel@tonic-gate u_char *inp; 478*7c478bd9Sstevel@tonic-gate int len; 479*7c478bd9Sstevel@tonic-gate { 480*7c478bd9Sstevel@tonic-gate switch (code) { 481*7c478bd9Sstevel@tonic-gate case CCP_RESETREQ: 482*7c478bd9Sstevel@tonic-gate if (!(ccp_localstate[f->unit] & RREQ_REJECTED)) { 483*7c478bd9Sstevel@tonic-gate info("peer has rejected CCP Reset-Request; falling back on Open"); 484*7c478bd9Sstevel@tonic-gate if (f->state == OPENED) 485*7c478bd9Sstevel@tonic-gate ccp_open(f->unit); 486*7c478bd9Sstevel@tonic-gate } 487*7c478bd9Sstevel@tonic-gate ccp_localstate[f->unit] |= RREQ_REJECTED; 488*7c478bd9Sstevel@tonic-gate return (0); 489*7c478bd9Sstevel@tonic-gate 490*7c478bd9Sstevel@tonic-gate case CCP_RESETACK: 491*7c478bd9Sstevel@tonic-gate /* 492*7c478bd9Sstevel@tonic-gate * Peer must have sent us CCP Reset-Request but then code-rejected 493*7c478bd9Sstevel@tonic-gate * when we sent CCP Reset-Ack. He's a moron, be we have to obey 494*7c478bd9Sstevel@tonic-gate * his wishes. 495*7c478bd9Sstevel@tonic-gate */ 496*7c478bd9Sstevel@tonic-gate ccp_localstate[f->unit] |= RACK_REJECTED; 497*7c478bd9Sstevel@tonic-gate notice("peer has erroneously rejected CCP Reset-Ack"); 498*7c478bd9Sstevel@tonic-gate f->term_reason = "peer sent Code-Reject for CCP Reset-Ack"; 499*7c478bd9Sstevel@tonic-gate f->term_reason_len = strlen(f->term_reason); 500*7c478bd9Sstevel@tonic-gate break; 501*7c478bd9Sstevel@tonic-gate 502*7c478bd9Sstevel@tonic-gate default: 503*7c478bd9Sstevel@tonic-gate f->term_reason = "peer sent invalid Code-Reject"; 504*7c478bd9Sstevel@tonic-gate break; 505*7c478bd9Sstevel@tonic-gate } 506*7c478bd9Sstevel@tonic-gate 507*7c478bd9Sstevel@tonic-gate f->term_reason_len = strlen(f->term_reason); 508*7c478bd9Sstevel@tonic-gate return (1); 509*7c478bd9Sstevel@tonic-gate } 510*7c478bd9Sstevel@tonic-gate 511*7c478bd9Sstevel@tonic-gate /* 512*7c478bd9Sstevel@tonic-gate * ccp_protrej - peer doesn't talk CCP. 513*7c478bd9Sstevel@tonic-gate */ 514*7c478bd9Sstevel@tonic-gate static void 515*7c478bd9Sstevel@tonic-gate ccp_protrej(unit) 516*7c478bd9Sstevel@tonic-gate int unit; 517*7c478bd9Sstevel@tonic-gate { 518*7c478bd9Sstevel@tonic-gate /* Neither open nor up. */ 519*7c478bd9Sstevel@tonic-gate ccp_flags_set(unit, 0, 0); 520*7c478bd9Sstevel@tonic-gate fsm_lowerdown(&ccp_fsm[unit]); 521*7c478bd9Sstevel@tonic-gate } 522*7c478bd9Sstevel@tonic-gate 523*7c478bd9Sstevel@tonic-gate /* 524*7c478bd9Sstevel@tonic-gate * ccp_resetci - initialize at start of negotiation. 525*7c478bd9Sstevel@tonic-gate */ 526*7c478bd9Sstevel@tonic-gate static void 527*7c478bd9Sstevel@tonic-gate ccp_resetci(f) 528*7c478bd9Sstevel@tonic-gate fsm *f; 529*7c478bd9Sstevel@tonic-gate { 530*7c478bd9Sstevel@tonic-gate ccp_options *go = &ccp_gotoptions[f->unit]; 531*7c478bd9Sstevel@tonic-gate u_char opt_buf[16]; 532*7c478bd9Sstevel@tonic-gate 533*7c478bd9Sstevel@tonic-gate *go = ccp_wantoptions[f->unit]; 534*7c478bd9Sstevel@tonic-gate all_rejected[f->unit] = 0; 535*7c478bd9Sstevel@tonic-gate 536*7c478bd9Sstevel@tonic-gate /* 537*7c478bd9Sstevel@tonic-gate * Check whether the kernel knows about the various 538*7c478bd9Sstevel@tonic-gate * decompression methods we might request. 539*7c478bd9Sstevel@tonic-gate */ 540*7c478bd9Sstevel@tonic-gate if (go->bsd_compress) { 541*7c478bd9Sstevel@tonic-gate opt_buf[0] = CI_BSD_COMPRESS; 542*7c478bd9Sstevel@tonic-gate opt_buf[1] = CILEN_BSD_COMPRESS; 543*7c478bd9Sstevel@tonic-gate opt_buf[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, BSD_MIN_BITS); 544*7c478bd9Sstevel@tonic-gate if (ccp_test(f->unit, opt_buf, CILEN_BSD_COMPRESS, 0) <= 0) 545*7c478bd9Sstevel@tonic-gate go->bsd_compress = 0; 546*7c478bd9Sstevel@tonic-gate } 547*7c478bd9Sstevel@tonic-gate if (go->deflate) { 548*7c478bd9Sstevel@tonic-gate if (go->deflate_correct) { 549*7c478bd9Sstevel@tonic-gate opt_buf[0] = CI_DEFLATE; 550*7c478bd9Sstevel@tonic-gate opt_buf[1] = CILEN_DEFLATE; 551*7c478bd9Sstevel@tonic-gate opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_SIZE+1); 552*7c478bd9Sstevel@tonic-gate opt_buf[3] = DEFLATE_CHK_SEQUENCE; 553*7c478bd9Sstevel@tonic-gate if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0) 554*7c478bd9Sstevel@tonic-gate go->deflate_correct = 0; 555*7c478bd9Sstevel@tonic-gate } 556*7c478bd9Sstevel@tonic-gate if (go->deflate_draft) { 557*7c478bd9Sstevel@tonic-gate opt_buf[0] = CI_DEFLATE_DRAFT; 558*7c478bd9Sstevel@tonic-gate opt_buf[1] = CILEN_DEFLATE; 559*7c478bd9Sstevel@tonic-gate opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_SIZE+1); 560*7c478bd9Sstevel@tonic-gate opt_buf[3] = DEFLATE_CHK_SEQUENCE; 561*7c478bd9Sstevel@tonic-gate if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0) 562*7c478bd9Sstevel@tonic-gate go->deflate_draft = 0; 563*7c478bd9Sstevel@tonic-gate } 564*7c478bd9Sstevel@tonic-gate if (!go->deflate_correct && !go->deflate_draft) 565*7c478bd9Sstevel@tonic-gate go->deflate = 0; 566*7c478bd9Sstevel@tonic-gate } 567*7c478bd9Sstevel@tonic-gate if (go->predictor_1) { 568*7c478bd9Sstevel@tonic-gate opt_buf[0] = CI_PREDICTOR_1; 569*7c478bd9Sstevel@tonic-gate opt_buf[1] = CILEN_PREDICTOR_1; 570*7c478bd9Sstevel@tonic-gate if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_1, 0) <= 0) 571*7c478bd9Sstevel@tonic-gate go->predictor_1 = 0; 572*7c478bd9Sstevel@tonic-gate } 573*7c478bd9Sstevel@tonic-gate if (go->predictor_2) { 574*7c478bd9Sstevel@tonic-gate opt_buf[0] = CI_PREDICTOR_2; 575*7c478bd9Sstevel@tonic-gate opt_buf[1] = CILEN_PREDICTOR_2; 576*7c478bd9Sstevel@tonic-gate if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_2, 0) <= 0) 577*7c478bd9Sstevel@tonic-gate go->predictor_2 = 0; 578*7c478bd9Sstevel@tonic-gate } 579*7c478bd9Sstevel@tonic-gate } 580*7c478bd9Sstevel@tonic-gate 581*7c478bd9Sstevel@tonic-gate /* 582*7c478bd9Sstevel@tonic-gate * ccp_cilen - Return total length of our configuration info. 583*7c478bd9Sstevel@tonic-gate */ 584*7c478bd9Sstevel@tonic-gate static int 585*7c478bd9Sstevel@tonic-gate ccp_cilen(f) 586*7c478bd9Sstevel@tonic-gate fsm *f; 587*7c478bd9Sstevel@tonic-gate { 588*7c478bd9Sstevel@tonic-gate ccp_options *go = &ccp_gotoptions[f->unit]; 589*7c478bd9Sstevel@tonic-gate 590*7c478bd9Sstevel@tonic-gate return (go->bsd_compress? CILEN_BSD_COMPRESS: 0) 591*7c478bd9Sstevel@tonic-gate + (go->deflate && go->deflate_correct ? CILEN_DEFLATE : 0) 592*7c478bd9Sstevel@tonic-gate + (go->deflate && go->deflate_draft ? CILEN_DEFLATE : 0) 593*7c478bd9Sstevel@tonic-gate + (go->predictor_1? CILEN_PREDICTOR_1: 0) 594*7c478bd9Sstevel@tonic-gate + (go->predictor_2? CILEN_PREDICTOR_2: 0); 595*7c478bd9Sstevel@tonic-gate } 596*7c478bd9Sstevel@tonic-gate 597*7c478bd9Sstevel@tonic-gate /* 598*7c478bd9Sstevel@tonic-gate * ccp_addci - put our requests in a packet. 599*7c478bd9Sstevel@tonic-gate */ 600*7c478bd9Sstevel@tonic-gate static void 601*7c478bd9Sstevel@tonic-gate ccp_addci(f, p, lenp) 602*7c478bd9Sstevel@tonic-gate fsm *f; 603*7c478bd9Sstevel@tonic-gate u_char *p; 604*7c478bd9Sstevel@tonic-gate int *lenp; 605*7c478bd9Sstevel@tonic-gate { 606*7c478bd9Sstevel@tonic-gate int res; 607*7c478bd9Sstevel@tonic-gate ccp_options *go = &ccp_gotoptions[f->unit]; 608*7c478bd9Sstevel@tonic-gate u_char *p0 = p; 609*7c478bd9Sstevel@tonic-gate 610*7c478bd9Sstevel@tonic-gate /* 611*7c478bd9Sstevel@tonic-gate * Add the compression types that we can receive, in decreasing 612*7c478bd9Sstevel@tonic-gate * preference order. Get the kernel to allocate the first one 613*7c478bd9Sstevel@tonic-gate * in case it gets Acked. 614*7c478bd9Sstevel@tonic-gate */ 615*7c478bd9Sstevel@tonic-gate if (go->deflate) { 616*7c478bd9Sstevel@tonic-gate p[0] = go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT; 617*7c478bd9Sstevel@tonic-gate p[1] = CILEN_DEFLATE; 618*7c478bd9Sstevel@tonic-gate p[2] = DEFLATE_MAKE_OPT(go->deflate_size); 619*7c478bd9Sstevel@tonic-gate p[3] = DEFLATE_CHK_SEQUENCE; 620*7c478bd9Sstevel@tonic-gate for (;;) { 621*7c478bd9Sstevel@tonic-gate res = ccp_test(f->unit, p, CILEN_DEFLATE, 0); 622*7c478bd9Sstevel@tonic-gate if (res > 0) { 623*7c478bd9Sstevel@tonic-gate p += CILEN_DEFLATE; 624*7c478bd9Sstevel@tonic-gate break; 625*7c478bd9Sstevel@tonic-gate } 626*7c478bd9Sstevel@tonic-gate if (res < 0 || go->deflate_size <= DEFLATE_MIN_SIZE+1) { 627*7c478bd9Sstevel@tonic-gate go->deflate = 0; 628*7c478bd9Sstevel@tonic-gate break; 629*7c478bd9Sstevel@tonic-gate } 630*7c478bd9Sstevel@tonic-gate --go->deflate_size; 631*7c478bd9Sstevel@tonic-gate p[2] = DEFLATE_MAKE_OPT(go->deflate_size); 632*7c478bd9Sstevel@tonic-gate } 633*7c478bd9Sstevel@tonic-gate /* If we're offering both, then this is second. */ 634*7c478bd9Sstevel@tonic-gate if (p != p0 && go->deflate_correct && go->deflate_draft) { 635*7c478bd9Sstevel@tonic-gate p[0] = CI_DEFLATE_DRAFT; 636*7c478bd9Sstevel@tonic-gate p[1] = CILEN_DEFLATE; 637*7c478bd9Sstevel@tonic-gate p[2] = p[2 - CILEN_DEFLATE]; 638*7c478bd9Sstevel@tonic-gate p[3] = DEFLATE_CHK_SEQUENCE; 639*7c478bd9Sstevel@tonic-gate p += CILEN_DEFLATE; 640*7c478bd9Sstevel@tonic-gate } 641*7c478bd9Sstevel@tonic-gate } 642*7c478bd9Sstevel@tonic-gate if (go->bsd_compress) { 643*7c478bd9Sstevel@tonic-gate p[0] = CI_BSD_COMPRESS; 644*7c478bd9Sstevel@tonic-gate p[1] = CILEN_BSD_COMPRESS; 645*7c478bd9Sstevel@tonic-gate p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits); 646*7c478bd9Sstevel@tonic-gate if (p != p0) { 647*7c478bd9Sstevel@tonic-gate p += CILEN_BSD_COMPRESS; /* not the first option */ 648*7c478bd9Sstevel@tonic-gate } else { 649*7c478bd9Sstevel@tonic-gate for (;;) { 650*7c478bd9Sstevel@tonic-gate res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 0); 651*7c478bd9Sstevel@tonic-gate if (res > 0) { 652*7c478bd9Sstevel@tonic-gate p += CILEN_BSD_COMPRESS; 653*7c478bd9Sstevel@tonic-gate break; 654*7c478bd9Sstevel@tonic-gate } 655*7c478bd9Sstevel@tonic-gate if (res < 0 || go->bsd_bits <= BSD_MIN_BITS) { 656*7c478bd9Sstevel@tonic-gate go->bsd_compress = 0; 657*7c478bd9Sstevel@tonic-gate break; 658*7c478bd9Sstevel@tonic-gate } 659*7c478bd9Sstevel@tonic-gate --go->bsd_bits; 660*7c478bd9Sstevel@tonic-gate p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits); 661*7c478bd9Sstevel@tonic-gate } 662*7c478bd9Sstevel@tonic-gate } 663*7c478bd9Sstevel@tonic-gate } 664*7c478bd9Sstevel@tonic-gate /* 665*7c478bd9Sstevel@tonic-gate * Prefer Predictor-1 over Predictor-2. (The latter requires the use 666*7c478bd9Sstevel@tonic-gate * of LAP-B and has no known implementations.) 667*7c478bd9Sstevel@tonic-gate */ 668*7c478bd9Sstevel@tonic-gate if (go->predictor_1) { 669*7c478bd9Sstevel@tonic-gate p[0] = CI_PREDICTOR_1; 670*7c478bd9Sstevel@tonic-gate p[1] = CILEN_PREDICTOR_1; 671*7c478bd9Sstevel@tonic-gate if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_1, 0) <= 0) { 672*7c478bd9Sstevel@tonic-gate go->predictor_1 = 0; 673*7c478bd9Sstevel@tonic-gate } else { 674*7c478bd9Sstevel@tonic-gate p += CILEN_PREDICTOR_1; 675*7c478bd9Sstevel@tonic-gate } 676*7c478bd9Sstevel@tonic-gate } 677*7c478bd9Sstevel@tonic-gate if (go->predictor_2) { 678*7c478bd9Sstevel@tonic-gate p[0] = CI_PREDICTOR_2; 679*7c478bd9Sstevel@tonic-gate p[1] = CILEN_PREDICTOR_2; 680*7c478bd9Sstevel@tonic-gate if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_2, 0) <= 0) { 681*7c478bd9Sstevel@tonic-gate go->predictor_2 = 0; 682*7c478bd9Sstevel@tonic-gate } else { 683*7c478bd9Sstevel@tonic-gate p += CILEN_PREDICTOR_2; 684*7c478bd9Sstevel@tonic-gate } 685*7c478bd9Sstevel@tonic-gate } 686*7c478bd9Sstevel@tonic-gate 687*7c478bd9Sstevel@tonic-gate go->method = (p > p0)? p0[0]: -1; 688*7c478bd9Sstevel@tonic-gate 689*7c478bd9Sstevel@tonic-gate *lenp = p - p0; 690*7c478bd9Sstevel@tonic-gate } 691*7c478bd9Sstevel@tonic-gate 692*7c478bd9Sstevel@tonic-gate /* 693*7c478bd9Sstevel@tonic-gate * ccp_ackci - process a received configure-ack, and return 694*7c478bd9Sstevel@tonic-gate * 1 iff the packet was OK. 695*7c478bd9Sstevel@tonic-gate */ 696*7c478bd9Sstevel@tonic-gate static int 697*7c478bd9Sstevel@tonic-gate ccp_ackci(f, p, len) 698*7c478bd9Sstevel@tonic-gate fsm *f; 699*7c478bd9Sstevel@tonic-gate u_char *p; 700*7c478bd9Sstevel@tonic-gate int len; 701*7c478bd9Sstevel@tonic-gate { 702*7c478bd9Sstevel@tonic-gate ccp_options *go = &ccp_gotoptions[f->unit]; 703*7c478bd9Sstevel@tonic-gate u_char *p0 = p; 704*7c478bd9Sstevel@tonic-gate 705*7c478bd9Sstevel@tonic-gate if (go->deflate && go->deflate_correct) { 706*7c478bd9Sstevel@tonic-gate if (len < CILEN_DEFLATE 707*7c478bd9Sstevel@tonic-gate || p[0] != CI_DEFLATE || p[1] != CILEN_DEFLATE 708*7c478bd9Sstevel@tonic-gate || p[2] != DEFLATE_MAKE_OPT(go->deflate_size) 709*7c478bd9Sstevel@tonic-gate || p[3] != DEFLATE_CHK_SEQUENCE) 710*7c478bd9Sstevel@tonic-gate return 0; 711*7c478bd9Sstevel@tonic-gate /* Cope with non-standard first/fast ack */ 712*7c478bd9Sstevel@tonic-gate if (p == p0 && len == 0) 713*7c478bd9Sstevel@tonic-gate return 1; 714*7c478bd9Sstevel@tonic-gate p += CILEN_DEFLATE; 715*7c478bd9Sstevel@tonic-gate len -= CILEN_DEFLATE; 716*7c478bd9Sstevel@tonic-gate } 717*7c478bd9Sstevel@tonic-gate if (go->deflate && go->deflate_draft) { 718*7c478bd9Sstevel@tonic-gate if (len < CILEN_DEFLATE 719*7c478bd9Sstevel@tonic-gate || p[0] != CI_DEFLATE_DRAFT || p[1] != CILEN_DEFLATE 720*7c478bd9Sstevel@tonic-gate || p[2] != DEFLATE_MAKE_OPT(go->deflate_size) 721*7c478bd9Sstevel@tonic-gate || p[3] != DEFLATE_CHK_SEQUENCE) 722*7c478bd9Sstevel@tonic-gate return 0; 723*7c478bd9Sstevel@tonic-gate /* Cope with non-standard first/fast ack */ 724*7c478bd9Sstevel@tonic-gate if (p == p0 && len == 0) 725*7c478bd9Sstevel@tonic-gate return 1; 726*7c478bd9Sstevel@tonic-gate p += CILEN_DEFLATE; 727*7c478bd9Sstevel@tonic-gate len -= CILEN_DEFLATE; 728*7c478bd9Sstevel@tonic-gate } 729*7c478bd9Sstevel@tonic-gate if (go->bsd_compress) { 730*7c478bd9Sstevel@tonic-gate if (len < CILEN_BSD_COMPRESS 731*7c478bd9Sstevel@tonic-gate || p[0] != CI_BSD_COMPRESS || p[1] != CILEN_BSD_COMPRESS 732*7c478bd9Sstevel@tonic-gate || p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits)) 733*7c478bd9Sstevel@tonic-gate return 0; 734*7c478bd9Sstevel@tonic-gate /* Cope with non-standard first/fast ack */ 735*7c478bd9Sstevel@tonic-gate if (p == p0 && len == 0) 736*7c478bd9Sstevel@tonic-gate return 1; 737*7c478bd9Sstevel@tonic-gate p += CILEN_BSD_COMPRESS; 738*7c478bd9Sstevel@tonic-gate len -= CILEN_BSD_COMPRESS; 739*7c478bd9Sstevel@tonic-gate } 740*7c478bd9Sstevel@tonic-gate if (go->predictor_1) { 741*7c478bd9Sstevel@tonic-gate if (len < CILEN_PREDICTOR_1 742*7c478bd9Sstevel@tonic-gate || p[0] != CI_PREDICTOR_1 || p[1] != CILEN_PREDICTOR_1) 743*7c478bd9Sstevel@tonic-gate return 0; 744*7c478bd9Sstevel@tonic-gate /* Cope with non-standard first/fast ack */ 745*7c478bd9Sstevel@tonic-gate if (p == p0 && len == 0) 746*7c478bd9Sstevel@tonic-gate return 1; 747*7c478bd9Sstevel@tonic-gate p += CILEN_PREDICTOR_1; 748*7c478bd9Sstevel@tonic-gate len -= CILEN_PREDICTOR_1; 749*7c478bd9Sstevel@tonic-gate } 750*7c478bd9Sstevel@tonic-gate if (go->predictor_2) { 751*7c478bd9Sstevel@tonic-gate if (len < CILEN_PREDICTOR_2 752*7c478bd9Sstevel@tonic-gate || p[0] != CI_PREDICTOR_2 || p[1] != CILEN_PREDICTOR_2) 753*7c478bd9Sstevel@tonic-gate return 0; 754*7c478bd9Sstevel@tonic-gate /* Cope with non-standard first/fast ack */ 755*7c478bd9Sstevel@tonic-gate if (p == p0 && len == 0) 756*7c478bd9Sstevel@tonic-gate return 1; 757*7c478bd9Sstevel@tonic-gate p += CILEN_PREDICTOR_2; 758*7c478bd9Sstevel@tonic-gate len -= CILEN_PREDICTOR_2; 759*7c478bd9Sstevel@tonic-gate } 760*7c478bd9Sstevel@tonic-gate 761*7c478bd9Sstevel@tonic-gate /* Peer cannot ack something that wasn't sent. */ 762*7c478bd9Sstevel@tonic-gate if (len != 0) 763*7c478bd9Sstevel@tonic-gate return 0; 764*7c478bd9Sstevel@tonic-gate return 1; 765*7c478bd9Sstevel@tonic-gate } 766*7c478bd9Sstevel@tonic-gate 767*7c478bd9Sstevel@tonic-gate /* 768*7c478bd9Sstevel@tonic-gate * ccp_nakci - process received configure-nak. 769*7c478bd9Sstevel@tonic-gate * Returns 1 iff the nak was OK. 770*7c478bd9Sstevel@tonic-gate */ 771*7c478bd9Sstevel@tonic-gate static int 772*7c478bd9Sstevel@tonic-gate ccp_nakci(f, p, len) 773*7c478bd9Sstevel@tonic-gate fsm *f; 774*7c478bd9Sstevel@tonic-gate u_char *p; 775*7c478bd9Sstevel@tonic-gate int len; 776*7c478bd9Sstevel@tonic-gate { 777*7c478bd9Sstevel@tonic-gate ccp_options *go = &ccp_gotoptions[f->unit]; 778*7c478bd9Sstevel@tonic-gate ccp_options no; /* options we've seen already */ 779*7c478bd9Sstevel@tonic-gate ccp_options try; /* options to ask for next time */ 780*7c478bd9Sstevel@tonic-gate 781*7c478bd9Sstevel@tonic-gate BZERO(&no, sizeof(no)); 782*7c478bd9Sstevel@tonic-gate try = *go; 783*7c478bd9Sstevel@tonic-gate 784*7c478bd9Sstevel@tonic-gate if (go->deflate && go->deflate_correct && len >= CILEN_DEFLATE && 785*7c478bd9Sstevel@tonic-gate p[0] == CI_DEFLATE) { 786*7c478bd9Sstevel@tonic-gate no.deflate = 1; 787*7c478bd9Sstevel@tonic-gate /* 788*7c478bd9Sstevel@tonic-gate * Peer wants us to use a different code size or something. 789*7c478bd9Sstevel@tonic-gate * Stop asking for Deflate if we don't understand his suggestion. 790*7c478bd9Sstevel@tonic-gate */ 791*7c478bd9Sstevel@tonic-gate if (p[1] != CILEN_DEFLATE 792*7c478bd9Sstevel@tonic-gate || DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL 793*7c478bd9Sstevel@tonic-gate || DEFLATE_SIZE(p[2]) <= DEFLATE_MIN_SIZE 794*7c478bd9Sstevel@tonic-gate || p[3] != DEFLATE_CHK_SEQUENCE) 795*7c478bd9Sstevel@tonic-gate try.deflate_correct = 0; 796*7c478bd9Sstevel@tonic-gate else if (DEFLATE_SIZE(p[2]) < go->deflate_size) 797*7c478bd9Sstevel@tonic-gate try.deflate_size = DEFLATE_SIZE(p[2]); 798*7c478bd9Sstevel@tonic-gate len -= p[1]; 799*7c478bd9Sstevel@tonic-gate p += p[1]; 800*7c478bd9Sstevel@tonic-gate } 801*7c478bd9Sstevel@tonic-gate 802*7c478bd9Sstevel@tonic-gate if (go->deflate && go->deflate_draft && len >= CILEN_DEFLATE && 803*7c478bd9Sstevel@tonic-gate p[0] == CI_DEFLATE_DRAFT) { 804*7c478bd9Sstevel@tonic-gate no.deflate = 1; 805*7c478bd9Sstevel@tonic-gate /* 806*7c478bd9Sstevel@tonic-gate * Peer wants us to use a different code size or something. 807*7c478bd9Sstevel@tonic-gate * Stop asking for Deflate using the old algorithm number if 808*7c478bd9Sstevel@tonic-gate * we don't understand his suggestion. (Note that this will 809*7c478bd9Sstevel@tonic-gate * happen if the peer is running Magnalink instead of 810*7c478bd9Sstevel@tonic-gate * old-style Deflate.) 811*7c478bd9Sstevel@tonic-gate */ 812*7c478bd9Sstevel@tonic-gate if (p[1] != CILEN_DEFLATE 813*7c478bd9Sstevel@tonic-gate || DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL 814*7c478bd9Sstevel@tonic-gate || DEFLATE_SIZE(p[2]) <= DEFLATE_MIN_SIZE 815*7c478bd9Sstevel@tonic-gate || p[3] != DEFLATE_CHK_SEQUENCE) 816*7c478bd9Sstevel@tonic-gate try.deflate_draft = 0; 817*7c478bd9Sstevel@tonic-gate else if (DEFLATE_SIZE(p[2]) < go->deflate_size) 818*7c478bd9Sstevel@tonic-gate try.deflate_size = DEFLATE_SIZE(p[2]); 819*7c478bd9Sstevel@tonic-gate len -= p[1]; 820*7c478bd9Sstevel@tonic-gate p += p[1]; 821*7c478bd9Sstevel@tonic-gate } 822*7c478bd9Sstevel@tonic-gate 823*7c478bd9Sstevel@tonic-gate if (!try.deflate_correct && !try.deflate_draft) 824*7c478bd9Sstevel@tonic-gate try.deflate = 0; 825*7c478bd9Sstevel@tonic-gate 826*7c478bd9Sstevel@tonic-gate if (go->bsd_compress && len >= CILEN_BSD_COMPRESS && 827*7c478bd9Sstevel@tonic-gate p[0] == CI_BSD_COMPRESS) { 828*7c478bd9Sstevel@tonic-gate no.bsd_compress = 1; 829*7c478bd9Sstevel@tonic-gate /* 830*7c478bd9Sstevel@tonic-gate * Peer wants us to use a different number of bits 831*7c478bd9Sstevel@tonic-gate * or a different version. 832*7c478bd9Sstevel@tonic-gate */ 833*7c478bd9Sstevel@tonic-gate if (p[1] != CILEN_BSD_COMPRESS || 834*7c478bd9Sstevel@tonic-gate BSD_VERSION(p[2]) != BSD_CURRENT_VERSION) 835*7c478bd9Sstevel@tonic-gate try.bsd_compress = 0; 836*7c478bd9Sstevel@tonic-gate else if (BSD_NBITS(p[2]) < go->bsd_bits) 837*7c478bd9Sstevel@tonic-gate try.bsd_bits = BSD_NBITS(p[2]); 838*7c478bd9Sstevel@tonic-gate len -= p[1]; 839*7c478bd9Sstevel@tonic-gate p += p[1]; 840*7c478bd9Sstevel@tonic-gate } 841*7c478bd9Sstevel@tonic-gate 842*7c478bd9Sstevel@tonic-gate /* 843*7c478bd9Sstevel@tonic-gate * Predictor-1 and 2 have no options, so they can't be Naked. 844*7c478bd9Sstevel@tonic-gate * 845*7c478bd9Sstevel@tonic-gate * There may be remaining options but we ignore them. 846*7c478bd9Sstevel@tonic-gate */ 847*7c478bd9Sstevel@tonic-gate 848*7c478bd9Sstevel@tonic-gate if (f->state != OPENED) 849*7c478bd9Sstevel@tonic-gate *go = try; 850*7c478bd9Sstevel@tonic-gate return 1; 851*7c478bd9Sstevel@tonic-gate } 852*7c478bd9Sstevel@tonic-gate 853*7c478bd9Sstevel@tonic-gate /* 854*7c478bd9Sstevel@tonic-gate * ccp_rejci - peer rejects some of our suggested compression methods. 855*7c478bd9Sstevel@tonic-gate */ 856*7c478bd9Sstevel@tonic-gate static int 857*7c478bd9Sstevel@tonic-gate ccp_rejci(f, p, len) 858*7c478bd9Sstevel@tonic-gate fsm *f; 859*7c478bd9Sstevel@tonic-gate u_char *p; 860*7c478bd9Sstevel@tonic-gate int len; 861*7c478bd9Sstevel@tonic-gate { 862*7c478bd9Sstevel@tonic-gate ccp_options *go = &ccp_gotoptions[f->unit]; 863*7c478bd9Sstevel@tonic-gate ccp_options try; /* options to request next time */ 864*7c478bd9Sstevel@tonic-gate 865*7c478bd9Sstevel@tonic-gate try = *go; 866*7c478bd9Sstevel@tonic-gate 867*7c478bd9Sstevel@tonic-gate /* 868*7c478bd9Sstevel@tonic-gate * Cope with empty configure-rejects by ceasing to send 869*7c478bd9Sstevel@tonic-gate * configure-requests. 870*7c478bd9Sstevel@tonic-gate */ 871*7c478bd9Sstevel@tonic-gate if (len == 0 && all_rejected[f->unit]) 872*7c478bd9Sstevel@tonic-gate return -1; 873*7c478bd9Sstevel@tonic-gate 874*7c478bd9Sstevel@tonic-gate if (go->deflate && go->deflate_correct && len >= CILEN_DEFLATE && 875*7c478bd9Sstevel@tonic-gate p[0] == CI_DEFLATE && p[1] == CILEN_DEFLATE) { 876*7c478bd9Sstevel@tonic-gate if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size) 877*7c478bd9Sstevel@tonic-gate || p[3] != DEFLATE_CHK_SEQUENCE) 878*7c478bd9Sstevel@tonic-gate return 0; /* Rej is bad */ 879*7c478bd9Sstevel@tonic-gate try.deflate_correct = 0; 880*7c478bd9Sstevel@tonic-gate p += CILEN_DEFLATE; 881*7c478bd9Sstevel@tonic-gate len -= CILEN_DEFLATE; 882*7c478bd9Sstevel@tonic-gate } 883*7c478bd9Sstevel@tonic-gate if (go->deflate && go->deflate_draft && len >= CILEN_DEFLATE && 884*7c478bd9Sstevel@tonic-gate p[0] == CI_DEFLATE_DRAFT && p[1] == CILEN_DEFLATE) { 885*7c478bd9Sstevel@tonic-gate if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size) 886*7c478bd9Sstevel@tonic-gate || p[3] != DEFLATE_CHK_SEQUENCE) 887*7c478bd9Sstevel@tonic-gate return 0; /* Rej is bad */ 888*7c478bd9Sstevel@tonic-gate try.deflate_draft = 0; 889*7c478bd9Sstevel@tonic-gate p += CILEN_DEFLATE; 890*7c478bd9Sstevel@tonic-gate len -= CILEN_DEFLATE; 891*7c478bd9Sstevel@tonic-gate } 892*7c478bd9Sstevel@tonic-gate if (!try.deflate_correct && !try.deflate_draft) 893*7c478bd9Sstevel@tonic-gate try.deflate = 0; 894*7c478bd9Sstevel@tonic-gate if (go->bsd_compress && len >= CILEN_BSD_COMPRESS 895*7c478bd9Sstevel@tonic-gate && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) { 896*7c478bd9Sstevel@tonic-gate if (p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits)) 897*7c478bd9Sstevel@tonic-gate return 0; 898*7c478bd9Sstevel@tonic-gate try.bsd_compress = 0; 899*7c478bd9Sstevel@tonic-gate p += CILEN_BSD_COMPRESS; 900*7c478bd9Sstevel@tonic-gate len -= CILEN_BSD_COMPRESS; 901*7c478bd9Sstevel@tonic-gate } 902*7c478bd9Sstevel@tonic-gate if (go->predictor_1 && len >= CILEN_PREDICTOR_1 903*7c478bd9Sstevel@tonic-gate && p[0] == CI_PREDICTOR_1 && p[1] == CILEN_PREDICTOR_1) { 904*7c478bd9Sstevel@tonic-gate try.predictor_1 = 0; 905*7c478bd9Sstevel@tonic-gate p += CILEN_PREDICTOR_1; 906*7c478bd9Sstevel@tonic-gate len -= CILEN_PREDICTOR_1; 907*7c478bd9Sstevel@tonic-gate } 908*7c478bd9Sstevel@tonic-gate if (go->predictor_2 && len >= CILEN_PREDICTOR_2 909*7c478bd9Sstevel@tonic-gate && p[0] == CI_PREDICTOR_2 && p[1] == CILEN_PREDICTOR_2) { 910*7c478bd9Sstevel@tonic-gate try.predictor_2 = 0; 911*7c478bd9Sstevel@tonic-gate p += CILEN_PREDICTOR_2; 912*7c478bd9Sstevel@tonic-gate len -= CILEN_PREDICTOR_2; 913*7c478bd9Sstevel@tonic-gate } 914*7c478bd9Sstevel@tonic-gate 915*7c478bd9Sstevel@tonic-gate if (len != 0) 916*7c478bd9Sstevel@tonic-gate return 0; 917*7c478bd9Sstevel@tonic-gate 918*7c478bd9Sstevel@tonic-gate if (f->state != OPENED) 919*7c478bd9Sstevel@tonic-gate *go = try; 920*7c478bd9Sstevel@tonic-gate 921*7c478bd9Sstevel@tonic-gate return 1; 922*7c478bd9Sstevel@tonic-gate } 923*7c478bd9Sstevel@tonic-gate 924*7c478bd9Sstevel@tonic-gate /* 925*7c478bd9Sstevel@tonic-gate * ccp_reqci - process a received configure-request. 926*7c478bd9Sstevel@tonic-gate * 927*7c478bd9Sstevel@tonic-gate * Returns CODE_CONFACK, CODE_CONFNAK or CODE_CONFREJ and the packet 928*7c478bd9Sstevel@tonic-gate * is modified appropriately. 929*7c478bd9Sstevel@tonic-gate */ 930*7c478bd9Sstevel@tonic-gate static int 931*7c478bd9Sstevel@tonic-gate ccp_reqci(f, p, lenp, dont_nak) 932*7c478bd9Sstevel@tonic-gate fsm *f; 933*7c478bd9Sstevel@tonic-gate u_char *p; 934*7c478bd9Sstevel@tonic-gate int *lenp; 935*7c478bd9Sstevel@tonic-gate int dont_nak; 936*7c478bd9Sstevel@tonic-gate { 937*7c478bd9Sstevel@tonic-gate int ret, newret, res; 938*7c478bd9Sstevel@tonic-gate u_char *p0, *nakp, *rejp, *pv; 939*7c478bd9Sstevel@tonic-gate int len, clen, type, nb; 940*7c478bd9Sstevel@tonic-gate ccp_options *ho = &ccp_hisoptions[f->unit]; 941*7c478bd9Sstevel@tonic-gate ccp_options *ao = &ccp_allowoptions[f->unit]; 942*7c478bd9Sstevel@tonic-gate 943*7c478bd9Sstevel@tonic-gate ret = CODE_CONFACK; 944*7c478bd9Sstevel@tonic-gate rejp = p0 = p; 945*7c478bd9Sstevel@tonic-gate nakp = nak_buffer; 946*7c478bd9Sstevel@tonic-gate len = *lenp; 947*7c478bd9Sstevel@tonic-gate 948*7c478bd9Sstevel@tonic-gate BZERO(ho, sizeof(ccp_options)); 949*7c478bd9Sstevel@tonic-gate ho->method = (len > 0)? p[0]: -1; 950*7c478bd9Sstevel@tonic-gate 951*7c478bd9Sstevel@tonic-gate for (; len > 0; len -= clen, p += clen) { 952*7c478bd9Sstevel@tonic-gate newret = CODE_CONFACK; 953*7c478bd9Sstevel@tonic-gate if (len < 2 || p[1] > len) { 954*7c478bd9Sstevel@tonic-gate /* 955*7c478bd9Sstevel@tonic-gate * RFC 1661 page 40 -- if the option extends beyond the 956*7c478bd9Sstevel@tonic-gate * packet, then discard the entire packet. 957*7c478bd9Sstevel@tonic-gate */ 958*7c478bd9Sstevel@tonic-gate return (0); 959*7c478bd9Sstevel@tonic-gate } 960*7c478bd9Sstevel@tonic-gate 961*7c478bd9Sstevel@tonic-gate type = p[0]; 962*7c478bd9Sstevel@tonic-gate clen = p[1]; 963*7c478bd9Sstevel@tonic-gate 964*7c478bd9Sstevel@tonic-gate pv = p; 965*7c478bd9Sstevel@tonic-gate switch (type) { 966*7c478bd9Sstevel@tonic-gate case CI_DEFLATE: 967*7c478bd9Sstevel@tonic-gate case CI_DEFLATE_DRAFT: 968*7c478bd9Sstevel@tonic-gate if (!ao->deflate || 969*7c478bd9Sstevel@tonic-gate (!ao->deflate_correct && type == CI_DEFLATE) || 970*7c478bd9Sstevel@tonic-gate (!ao->deflate_draft && type == CI_DEFLATE_DRAFT)) { 971*7c478bd9Sstevel@tonic-gate newret = CODE_CONFREJ; 972*7c478bd9Sstevel@tonic-gate break; 973*7c478bd9Sstevel@tonic-gate } 974*7c478bd9Sstevel@tonic-gate 975*7c478bd9Sstevel@tonic-gate ho->deflate = 1; 976*7c478bd9Sstevel@tonic-gate nb = clen < CILEN_DEFLATE ? ao->deflate_size : DEFLATE_SIZE(p[2]); 977*7c478bd9Sstevel@tonic-gate ho->deflate_size = nb; 978*7c478bd9Sstevel@tonic-gate if (clen != CILEN_DEFLATE || 979*7c478bd9Sstevel@tonic-gate DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL || 980*7c478bd9Sstevel@tonic-gate p[3] != DEFLATE_CHK_SEQUENCE || nb > ao->deflate_size || 981*7c478bd9Sstevel@tonic-gate nb <= DEFLATE_MIN_SIZE) { 982*7c478bd9Sstevel@tonic-gate newret = CODE_CONFNAK; 983*7c478bd9Sstevel@tonic-gate if (dont_nak) 984*7c478bd9Sstevel@tonic-gate break; 985*7c478bd9Sstevel@tonic-gate if (nb > ao->deflate_size) 986*7c478bd9Sstevel@tonic-gate nb = ao->deflate_size; 987*7c478bd9Sstevel@tonic-gate else if (nb <= DEFLATE_MIN_SIZE) 988*7c478bd9Sstevel@tonic-gate nb = DEFLATE_MIN_SIZE+1; 989*7c478bd9Sstevel@tonic-gate pv = nakp; 990*7c478bd9Sstevel@tonic-gate PUTCHAR(type, nakp); 991*7c478bd9Sstevel@tonic-gate PUTCHAR(CILEN_DEFLATE, nakp); 992*7c478bd9Sstevel@tonic-gate PUTCHAR(DEFLATE_MAKE_OPT(nb), nakp); 993*7c478bd9Sstevel@tonic-gate PUTCHAR(DEFLATE_CHK_SEQUENCE, nakp); 994*7c478bd9Sstevel@tonic-gate } 995*7c478bd9Sstevel@tonic-gate 996*7c478bd9Sstevel@tonic-gate /* 997*7c478bd9Sstevel@tonic-gate * Check whether we can do Deflate with the window 998*7c478bd9Sstevel@tonic-gate * size they want. If the window is too big, reduce 999*7c478bd9Sstevel@tonic-gate * it until the kernel can cope and nak with that. 1000*7c478bd9Sstevel@tonic-gate * We only check this for the first option. 1001*7c478bd9Sstevel@tonic-gate */ 1002*7c478bd9Sstevel@tonic-gate if (p == p0) { 1003*7c478bd9Sstevel@tonic-gate for (;;) { 1004*7c478bd9Sstevel@tonic-gate res = ccp_test(f->unit, pv, CILEN_DEFLATE, 1); 1005*7c478bd9Sstevel@tonic-gate if (res > 0) 1006*7c478bd9Sstevel@tonic-gate break; /* it's OK now */ 1007*7c478bd9Sstevel@tonic-gate if (res < 0 || nb <= DEFLATE_MIN_SIZE+1 || dont_nak) { 1008*7c478bd9Sstevel@tonic-gate newret = CODE_CONFREJ; 1009*7c478bd9Sstevel@tonic-gate break; 1010*7c478bd9Sstevel@tonic-gate } 1011*7c478bd9Sstevel@tonic-gate if (newret == CODE_CONFACK) { 1012*7c478bd9Sstevel@tonic-gate BCOPY(pv, nakp, CILEN_DEFLATE); 1013*7c478bd9Sstevel@tonic-gate pv = nakp; 1014*7c478bd9Sstevel@tonic-gate nakp += CILEN_DEFLATE; 1015*7c478bd9Sstevel@tonic-gate newret = CODE_CONFNAK; 1016*7c478bd9Sstevel@tonic-gate } 1017*7c478bd9Sstevel@tonic-gate --nb; 1018*7c478bd9Sstevel@tonic-gate pv[2] = DEFLATE_MAKE_OPT(nb); 1019*7c478bd9Sstevel@tonic-gate } 1020*7c478bd9Sstevel@tonic-gate #ifdef COMP_TUNE 1021*7c478bd9Sstevel@tonic-gate /* Tune Deflate compression effort. */ 1022*7c478bd9Sstevel@tonic-gate if (newret == CODE_CONFACK) 1023*7c478bd9Sstevel@tonic-gate ccp_tune(f->unit, deflate_tune); 1024*7c478bd9Sstevel@tonic-gate #endif 1025*7c478bd9Sstevel@tonic-gate } 1026*7c478bd9Sstevel@tonic-gate break; 1027*7c478bd9Sstevel@tonic-gate 1028*7c478bd9Sstevel@tonic-gate case CI_BSD_COMPRESS: 1029*7c478bd9Sstevel@tonic-gate if (!ao->bsd_compress) { 1030*7c478bd9Sstevel@tonic-gate newret = CODE_CONFREJ; 1031*7c478bd9Sstevel@tonic-gate break; 1032*7c478bd9Sstevel@tonic-gate } 1033*7c478bd9Sstevel@tonic-gate 1034*7c478bd9Sstevel@tonic-gate ho->bsd_compress = 1; 1035*7c478bd9Sstevel@tonic-gate nb = clen < CILEN_BSD_COMPRESS ? ao->bsd_bits : BSD_NBITS(p[2]); 1036*7c478bd9Sstevel@tonic-gate ho->bsd_bits = nb; 1037*7c478bd9Sstevel@tonic-gate if (clen != CILEN_BSD_COMPRESS || 1038*7c478bd9Sstevel@tonic-gate BSD_VERSION(p[2]) != BSD_CURRENT_VERSION || 1039*7c478bd9Sstevel@tonic-gate nb > ao->bsd_bits || nb < BSD_MIN_BITS) { 1040*7c478bd9Sstevel@tonic-gate newret = CODE_CONFNAK; 1041*7c478bd9Sstevel@tonic-gate if (dont_nak) 1042*7c478bd9Sstevel@tonic-gate break; 1043*7c478bd9Sstevel@tonic-gate if (nb > ao->bsd_bits) 1044*7c478bd9Sstevel@tonic-gate nb = ao->bsd_bits; 1045*7c478bd9Sstevel@tonic-gate else if (nb < BSD_MIN_BITS) 1046*7c478bd9Sstevel@tonic-gate nb = BSD_MIN_BITS; 1047*7c478bd9Sstevel@tonic-gate pv = nakp; 1048*7c478bd9Sstevel@tonic-gate PUTCHAR(type, nakp); 1049*7c478bd9Sstevel@tonic-gate PUTCHAR(CILEN_BSD_COMPRESS, nakp); 1050*7c478bd9Sstevel@tonic-gate PUTCHAR(BSD_MAKE_OPT(BSD_CURRENT_VERSION, nb), nakp); 1051*7c478bd9Sstevel@tonic-gate } 1052*7c478bd9Sstevel@tonic-gate 1053*7c478bd9Sstevel@tonic-gate /* 1054*7c478bd9Sstevel@tonic-gate * Check whether we can do BSD-Compress with the code 1055*7c478bd9Sstevel@tonic-gate * size they want. If the code size is too big, reduce 1056*7c478bd9Sstevel@tonic-gate * it until the kernel can cope and nak with that. 1057*7c478bd9Sstevel@tonic-gate * We only check this for the first option. 1058*7c478bd9Sstevel@tonic-gate */ 1059*7c478bd9Sstevel@tonic-gate if (p == p0) { 1060*7c478bd9Sstevel@tonic-gate for (;;) { 1061*7c478bd9Sstevel@tonic-gate res = ccp_test(f->unit, pv, CILEN_BSD_COMPRESS, 1); 1062*7c478bd9Sstevel@tonic-gate if (res > 0) 1063*7c478bd9Sstevel@tonic-gate break; 1064*7c478bd9Sstevel@tonic-gate if (res < 0 || nb == BSD_MIN_BITS || dont_nak) { 1065*7c478bd9Sstevel@tonic-gate newret = CODE_CONFREJ; 1066*7c478bd9Sstevel@tonic-gate break; 1067*7c478bd9Sstevel@tonic-gate } 1068*7c478bd9Sstevel@tonic-gate if (newret == CODE_CONFACK) { 1069*7c478bd9Sstevel@tonic-gate BCOPY(pv, nakp, CILEN_BSD_COMPRESS); 1070*7c478bd9Sstevel@tonic-gate pv = nakp; 1071*7c478bd9Sstevel@tonic-gate nakp += CILEN_BSD_COMPRESS; 1072*7c478bd9Sstevel@tonic-gate newret = CODE_CONFNAK; 1073*7c478bd9Sstevel@tonic-gate } 1074*7c478bd9Sstevel@tonic-gate --nb; 1075*7c478bd9Sstevel@tonic-gate pv[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, nb); 1076*7c478bd9Sstevel@tonic-gate } 1077*7c478bd9Sstevel@tonic-gate } 1078*7c478bd9Sstevel@tonic-gate break; 1079*7c478bd9Sstevel@tonic-gate 1080*7c478bd9Sstevel@tonic-gate case CI_PREDICTOR_1: 1081*7c478bd9Sstevel@tonic-gate if (!ao->predictor_1) { 1082*7c478bd9Sstevel@tonic-gate newret = CODE_CONFREJ; 1083*7c478bd9Sstevel@tonic-gate break; 1084*7c478bd9Sstevel@tonic-gate } 1085*7c478bd9Sstevel@tonic-gate 1086*7c478bd9Sstevel@tonic-gate ho->predictor_1 = 1; 1087*7c478bd9Sstevel@tonic-gate if (clen != CILEN_PREDICTOR_1) { 1088*7c478bd9Sstevel@tonic-gate newret = CODE_CONFNAK; 1089*7c478bd9Sstevel@tonic-gate if (dont_nak) 1090*7c478bd9Sstevel@tonic-gate break; 1091*7c478bd9Sstevel@tonic-gate pv = nakp; 1092*7c478bd9Sstevel@tonic-gate PUTCHAR(type, nakp); 1093*7c478bd9Sstevel@tonic-gate PUTCHAR(CILEN_PREDICTOR_1, nakp); 1094*7c478bd9Sstevel@tonic-gate } 1095*7c478bd9Sstevel@tonic-gate if (p == p0 && 1096*7c478bd9Sstevel@tonic-gate ccp_test(f->unit, pv, CILEN_PREDICTOR_1, 1) <= 0) { 1097*7c478bd9Sstevel@tonic-gate newret = CODE_CONFREJ; 1098*7c478bd9Sstevel@tonic-gate } 1099*7c478bd9Sstevel@tonic-gate break; 1100*7c478bd9Sstevel@tonic-gate 1101*7c478bd9Sstevel@tonic-gate case CI_PREDICTOR_2: 1102*7c478bd9Sstevel@tonic-gate if (!ao->predictor_2) { 1103*7c478bd9Sstevel@tonic-gate newret = CODE_CONFREJ; 1104*7c478bd9Sstevel@tonic-gate break; 1105*7c478bd9Sstevel@tonic-gate } 1106*7c478bd9Sstevel@tonic-gate 1107*7c478bd9Sstevel@tonic-gate ho->predictor_2 = 1; 1108*7c478bd9Sstevel@tonic-gate if (clen != CILEN_PREDICTOR_2) { 1109*7c478bd9Sstevel@tonic-gate newret = CODE_CONFNAK; 1110*7c478bd9Sstevel@tonic-gate if (dont_nak) 1111*7c478bd9Sstevel@tonic-gate break; 1112*7c478bd9Sstevel@tonic-gate pv = nakp; 1113*7c478bd9Sstevel@tonic-gate PUTCHAR(type, nakp); 1114*7c478bd9Sstevel@tonic-gate PUTCHAR(CILEN_PREDICTOR_2, nakp); 1115*7c478bd9Sstevel@tonic-gate } 1116*7c478bd9Sstevel@tonic-gate if (p == p0 && 1117*7c478bd9Sstevel@tonic-gate ccp_test(f->unit, p, CILEN_PREDICTOR_2, 1) <= 0) { 1118*7c478bd9Sstevel@tonic-gate newret = CODE_CONFREJ; 1119*7c478bd9Sstevel@tonic-gate } 1120*7c478bd9Sstevel@tonic-gate break; 1121*7c478bd9Sstevel@tonic-gate 1122*7c478bd9Sstevel@tonic-gate default: 1123*7c478bd9Sstevel@tonic-gate newret = CODE_CONFREJ; 1124*7c478bd9Sstevel@tonic-gate break; 1125*7c478bd9Sstevel@tonic-gate } 1126*7c478bd9Sstevel@tonic-gate 1127*7c478bd9Sstevel@tonic-gate /* Cope with confused peers. */ 1128*7c478bd9Sstevel@tonic-gate if (clen < 2) 1129*7c478bd9Sstevel@tonic-gate clen = 2; 1130*7c478bd9Sstevel@tonic-gate 1131*7c478bd9Sstevel@tonic-gate if (newret == CODE_CONFACK && ret != CODE_CONFACK) 1132*7c478bd9Sstevel@tonic-gate continue; 1133*7c478bd9Sstevel@tonic-gate if (newret == CODE_CONFNAK) { 1134*7c478bd9Sstevel@tonic-gate if (dont_nak) { 1135*7c478bd9Sstevel@tonic-gate newret = CODE_CONFREJ; 1136*7c478bd9Sstevel@tonic-gate } else { 1137*7c478bd9Sstevel@tonic-gate /* Ignore subsequent nakable things if rejecting. */ 1138*7c478bd9Sstevel@tonic-gate if (ret == CODE_CONFREJ) 1139*7c478bd9Sstevel@tonic-gate continue; 1140*7c478bd9Sstevel@tonic-gate ret = CODE_CONFNAK; 1141*7c478bd9Sstevel@tonic-gate } 1142*7c478bd9Sstevel@tonic-gate } 1143*7c478bd9Sstevel@tonic-gate if (newret == CODE_CONFREJ) { 1144*7c478bd9Sstevel@tonic-gate ret = CODE_CONFREJ; 1145*7c478bd9Sstevel@tonic-gate if (p != rejp) 1146*7c478bd9Sstevel@tonic-gate BCOPY(p, rejp, clen); 1147*7c478bd9Sstevel@tonic-gate rejp += clen; 1148*7c478bd9Sstevel@tonic-gate } 1149*7c478bd9Sstevel@tonic-gate } 1150*7c478bd9Sstevel@tonic-gate 1151*7c478bd9Sstevel@tonic-gate switch (ret) { 1152*7c478bd9Sstevel@tonic-gate case CODE_CONFACK: 1153*7c478bd9Sstevel@tonic-gate *lenp = p - p0; 1154*7c478bd9Sstevel@tonic-gate break; 1155*7c478bd9Sstevel@tonic-gate case CODE_CONFNAK: 1156*7c478bd9Sstevel@tonic-gate *lenp = nakp - nak_buffer; 1157*7c478bd9Sstevel@tonic-gate BCOPY(nak_buffer, p0, *lenp); 1158*7c478bd9Sstevel@tonic-gate break; 1159*7c478bd9Sstevel@tonic-gate case CODE_CONFREJ: 1160*7c478bd9Sstevel@tonic-gate *lenp = rejp - p0; 1161*7c478bd9Sstevel@tonic-gate break; 1162*7c478bd9Sstevel@tonic-gate } 1163*7c478bd9Sstevel@tonic-gate return ret; 1164*7c478bd9Sstevel@tonic-gate } 1165*7c478bd9Sstevel@tonic-gate 1166*7c478bd9Sstevel@tonic-gate /* 1167*7c478bd9Sstevel@tonic-gate * Make a string name for a compression method (or 2). 1168*7c478bd9Sstevel@tonic-gate */ 1169*7c478bd9Sstevel@tonic-gate static char * 1170*7c478bd9Sstevel@tonic-gate method_name(opt, opt2) 1171*7c478bd9Sstevel@tonic-gate ccp_options *opt, *opt2; 1172*7c478bd9Sstevel@tonic-gate { 1173*7c478bd9Sstevel@tonic-gate static char result[64]; 1174*7c478bd9Sstevel@tonic-gate 1175*7c478bd9Sstevel@tonic-gate if (!ANY_COMPRESS(*opt)) 1176*7c478bd9Sstevel@tonic-gate return "(none)"; 1177*7c478bd9Sstevel@tonic-gate switch (opt->method) { 1178*7c478bd9Sstevel@tonic-gate case CI_DEFLATE: 1179*7c478bd9Sstevel@tonic-gate case CI_DEFLATE_DRAFT: 1180*7c478bd9Sstevel@tonic-gate if (opt2 != NULL && opt2->deflate_size != opt->deflate_size) 1181*7c478bd9Sstevel@tonic-gate (void) slprintf(result, sizeof(result), "Deflate%s (%d/%d)", 1182*7c478bd9Sstevel@tonic-gate (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""), 1183*7c478bd9Sstevel@tonic-gate opt->deflate_size, opt2->deflate_size); 1184*7c478bd9Sstevel@tonic-gate else 1185*7c478bd9Sstevel@tonic-gate (void) slprintf(result, sizeof(result), "Deflate%s (%d)", 1186*7c478bd9Sstevel@tonic-gate (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""), 1187*7c478bd9Sstevel@tonic-gate opt->deflate_size); 1188*7c478bd9Sstevel@tonic-gate break; 1189*7c478bd9Sstevel@tonic-gate case CI_BSD_COMPRESS: 1190*7c478bd9Sstevel@tonic-gate if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits) 1191*7c478bd9Sstevel@tonic-gate (void) slprintf(result, sizeof(result), "BSD-Compress (%d/%d)", 1192*7c478bd9Sstevel@tonic-gate opt->bsd_bits, opt2->bsd_bits); 1193*7c478bd9Sstevel@tonic-gate else 1194*7c478bd9Sstevel@tonic-gate (void) slprintf(result, sizeof(result), "BSD-Compress (%d)", 1195*7c478bd9Sstevel@tonic-gate opt->bsd_bits); 1196*7c478bd9Sstevel@tonic-gate break; 1197*7c478bd9Sstevel@tonic-gate case CI_PREDICTOR_1: 1198*7c478bd9Sstevel@tonic-gate return "Predictor 1"; 1199*7c478bd9Sstevel@tonic-gate case CI_PREDICTOR_2: 1200*7c478bd9Sstevel@tonic-gate return "Predictor 2"; 1201*7c478bd9Sstevel@tonic-gate #ifdef CI_STAC 1202*7c478bd9Sstevel@tonic-gate case CI_STAC: 1203*7c478bd9Sstevel@tonic-gate return "Stac"; 1204*7c478bd9Sstevel@tonic-gate #endif 1205*7c478bd9Sstevel@tonic-gate #ifdef CI_MPPC 1206*7c478bd9Sstevel@tonic-gate case CI_MPPC: 1207*7c478bd9Sstevel@tonic-gate return "MS-PPC"; 1208*7c478bd9Sstevel@tonic-gate #endif 1209*7c478bd9Sstevel@tonic-gate default: 1210*7c478bd9Sstevel@tonic-gate (void) slprintf(result, sizeof(result), "Method %d", opt->method); 1211*7c478bd9Sstevel@tonic-gate } 1212*7c478bd9Sstevel@tonic-gate return result; 1213*7c478bd9Sstevel@tonic-gate } 1214*7c478bd9Sstevel@tonic-gate 1215*7c478bd9Sstevel@tonic-gate /* 1216*7c478bd9Sstevel@tonic-gate * CCP has come up - inform the kernel driver and log a message. 1217*7c478bd9Sstevel@tonic-gate */ 1218*7c478bd9Sstevel@tonic-gate static void 1219*7c478bd9Sstevel@tonic-gate ccp_up(f) 1220*7c478bd9Sstevel@tonic-gate fsm *f; 1221*7c478bd9Sstevel@tonic-gate { 1222*7c478bd9Sstevel@tonic-gate ccp_options *go = &ccp_gotoptions[f->unit]; 1223*7c478bd9Sstevel@tonic-gate ccp_options *ho = &ccp_hisoptions[f->unit]; 1224*7c478bd9Sstevel@tonic-gate char method1[64]; 1225*7c478bd9Sstevel@tonic-gate 1226*7c478bd9Sstevel@tonic-gate /* 1227*7c478bd9Sstevel@tonic-gate * We're now open and up (running). 1228*7c478bd9Sstevel@tonic-gate */ 1229*7c478bd9Sstevel@tonic-gate ccp_flags_set(f->unit, 1, 1); 1230*7c478bd9Sstevel@tonic-gate if (ANY_COMPRESS(*go)) { 1231*7c478bd9Sstevel@tonic-gate if (ANY_COMPRESS(*ho)) { 1232*7c478bd9Sstevel@tonic-gate if (go->method == ho->method) { 1233*7c478bd9Sstevel@tonic-gate notice("%s compression enabled", method_name(go, ho)); 1234*7c478bd9Sstevel@tonic-gate } else { 1235*7c478bd9Sstevel@tonic-gate (void) strlcpy(method1, method_name(go, NULL), sizeof(method1)); 1236*7c478bd9Sstevel@tonic-gate notice("%s / %s compression enabled", 1237*7c478bd9Sstevel@tonic-gate method1, method_name(ho, NULL)); 1238*7c478bd9Sstevel@tonic-gate } 1239*7c478bd9Sstevel@tonic-gate } else 1240*7c478bd9Sstevel@tonic-gate notice("%s receive decompression enabled", method_name(go, NULL)); 1241*7c478bd9Sstevel@tonic-gate } else if (ANY_COMPRESS(*ho)) 1242*7c478bd9Sstevel@tonic-gate notice("%s transmit compression enabled", method_name(ho, NULL)); 1243*7c478bd9Sstevel@tonic-gate } 1244*7c478bd9Sstevel@tonic-gate 1245*7c478bd9Sstevel@tonic-gate /* 1246*7c478bd9Sstevel@tonic-gate * CCP has gone down - inform the kernel driver. 1247*7c478bd9Sstevel@tonic-gate */ 1248*7c478bd9Sstevel@tonic-gate static void 1249*7c478bd9Sstevel@tonic-gate ccp_down(f) 1250*7c478bd9Sstevel@tonic-gate fsm *f; 1251*7c478bd9Sstevel@tonic-gate { 1252*7c478bd9Sstevel@tonic-gate if (ccp_localstate[f->unit] & RACK_PENDING) 1253*7c478bd9Sstevel@tonic-gate UNTIMEOUT(ccp_rack_timeout, f); 1254*7c478bd9Sstevel@tonic-gate /* Don't forget about peer's code rejects or ignoring of requests. */ 1255*7c478bd9Sstevel@tonic-gate ccp_localstate[f->unit] &= ~RACK_PENDING & ~RREQ_REPEAT; 1256*7c478bd9Sstevel@tonic-gate /* We're still open, but no longer up. */ 1257*7c478bd9Sstevel@tonic-gate ccp_flags_set(f->unit, 1, 0); 1258*7c478bd9Sstevel@tonic-gate } 1259*7c478bd9Sstevel@tonic-gate 1260*7c478bd9Sstevel@tonic-gate static int 1261*7c478bd9Sstevel@tonic-gate ccp_printpkt(p, plen, printer, arg) 1262*7c478bd9Sstevel@tonic-gate u_char *p; 1263*7c478bd9Sstevel@tonic-gate int plen; 1264*7c478bd9Sstevel@tonic-gate void (*printer) __P((void *, const char *, ...)); 1265*7c478bd9Sstevel@tonic-gate void *arg; 1266*7c478bd9Sstevel@tonic-gate { 1267*7c478bd9Sstevel@tonic-gate u_char *p0, *optend, cichar; 1268*7c478bd9Sstevel@tonic-gate int code, id, len; 1269*7c478bd9Sstevel@tonic-gate int optlen, clen; 1270*7c478bd9Sstevel@tonic-gate u_short cishort; 1271*7c478bd9Sstevel@tonic-gate #ifdef CI_MPPC 1272*7c478bd9Sstevel@tonic-gate u_int32_t cilong; 1273*7c478bd9Sstevel@tonic-gate #endif 1274*7c478bd9Sstevel@tonic-gate 1275*7c478bd9Sstevel@tonic-gate p0 = p; 1276*7c478bd9Sstevel@tonic-gate if (plen < HEADERLEN) { 1277*7c478bd9Sstevel@tonic-gate printer(arg, "too short (%d<%d)", plen, HEADERLEN); 1278*7c478bd9Sstevel@tonic-gate return (0); 1279*7c478bd9Sstevel@tonic-gate } 1280*7c478bd9Sstevel@tonic-gate GETCHAR(code, p); 1281*7c478bd9Sstevel@tonic-gate GETCHAR(id, p); 1282*7c478bd9Sstevel@tonic-gate GETSHORT(len, p); 1283*7c478bd9Sstevel@tonic-gate 1284*7c478bd9Sstevel@tonic-gate printer(arg, " %s id=0x%x", code_name(code, 1), id); 1285*7c478bd9Sstevel@tonic-gate 1286*7c478bd9Sstevel@tonic-gate if (len < HEADERLEN) { 1287*7c478bd9Sstevel@tonic-gate printer(arg, " header length %d<%d", len, HEADERLEN); 1288*7c478bd9Sstevel@tonic-gate return (HEADERLEN); 1289*7c478bd9Sstevel@tonic-gate } 1290*7c478bd9Sstevel@tonic-gate if (len > plen) { 1291*7c478bd9Sstevel@tonic-gate printer(arg, " truncated (%d>%d)", len, plen); 1292*7c478bd9Sstevel@tonic-gate len = plen; 1293*7c478bd9Sstevel@tonic-gate } 1294*7c478bd9Sstevel@tonic-gate len -= HEADERLEN; 1295*7c478bd9Sstevel@tonic-gate 1296*7c478bd9Sstevel@tonic-gate switch (code) { 1297*7c478bd9Sstevel@tonic-gate case CODE_CONFREQ: 1298*7c478bd9Sstevel@tonic-gate case CODE_CONFACK: 1299*7c478bd9Sstevel@tonic-gate case CODE_CONFNAK: 1300*7c478bd9Sstevel@tonic-gate case CODE_CONFREJ: 1301*7c478bd9Sstevel@tonic-gate /* print list of possible compression methods */ 1302*7c478bd9Sstevel@tonic-gate while (len >= 2) { 1303*7c478bd9Sstevel@tonic-gate GETCHAR(code, p); 1304*7c478bd9Sstevel@tonic-gate GETCHAR(clen, p); 1305*7c478bd9Sstevel@tonic-gate optlen = clen; 1306*7c478bd9Sstevel@tonic-gate printer(arg, " <"); 1307*7c478bd9Sstevel@tonic-gate if (optlen > len) 1308*7c478bd9Sstevel@tonic-gate optlen = len; 1309*7c478bd9Sstevel@tonic-gate if (optlen < 2) 1310*7c478bd9Sstevel@tonic-gate optlen = 2; 1311*7c478bd9Sstevel@tonic-gate len -= optlen; 1312*7c478bd9Sstevel@tonic-gate optend = p + optlen - 2; 1313*7c478bd9Sstevel@tonic-gate switch (code) { 1314*7c478bd9Sstevel@tonic-gate case CI_DEFLATE: 1315*7c478bd9Sstevel@tonic-gate case CI_DEFLATE_DRAFT: 1316*7c478bd9Sstevel@tonic-gate printer(arg, "deflate%s", 1317*7c478bd9Sstevel@tonic-gate (code == CI_DEFLATE_DRAFT? "(old#)": "")); 1318*7c478bd9Sstevel@tonic-gate if (clen != CILEN_DEFLATE) 1319*7c478bd9Sstevel@tonic-gate printer(arg, " length %d", clen); 1320*7c478bd9Sstevel@tonic-gate if (optlen >= CILEN_DEFLATE) { 1321*7c478bd9Sstevel@tonic-gate GETCHAR(cichar, p); 1322*7c478bd9Sstevel@tonic-gate printer(arg, " %d", DEFLATE_SIZE(cichar)); 1323*7c478bd9Sstevel@tonic-gate if (DEFLATE_METHOD(cichar) != DEFLATE_METHOD_VAL) 1324*7c478bd9Sstevel@tonic-gate printer(arg, " method %d", DEFLATE_METHOD(cichar)); 1325*7c478bd9Sstevel@tonic-gate GETCHAR(cichar, p); 1326*7c478bd9Sstevel@tonic-gate if (cichar != DEFLATE_CHK_SEQUENCE) 1327*7c478bd9Sstevel@tonic-gate printer(arg, " check %d", cichar); 1328*7c478bd9Sstevel@tonic-gate } 1329*7c478bd9Sstevel@tonic-gate break; 1330*7c478bd9Sstevel@tonic-gate case CI_BSD_COMPRESS: 1331*7c478bd9Sstevel@tonic-gate printer(arg, "bsd"); 1332*7c478bd9Sstevel@tonic-gate if (clen != CILEN_BSD_COMPRESS) 1333*7c478bd9Sstevel@tonic-gate printer(arg, " length %d", clen); 1334*7c478bd9Sstevel@tonic-gate if (optlen >= CILEN_BSD_COMPRESS) { 1335*7c478bd9Sstevel@tonic-gate GETCHAR(cichar, p); 1336*7c478bd9Sstevel@tonic-gate printer(arg, " v%d %d", BSD_VERSION(cichar), 1337*7c478bd9Sstevel@tonic-gate BSD_NBITS(cichar)); 1338*7c478bd9Sstevel@tonic-gate } 1339*7c478bd9Sstevel@tonic-gate break; 1340*7c478bd9Sstevel@tonic-gate case CI_PREDICTOR_1: 1341*7c478bd9Sstevel@tonic-gate printer(arg, "predictor-1"); 1342*7c478bd9Sstevel@tonic-gate if (clen != CILEN_PREDICTOR_1) 1343*7c478bd9Sstevel@tonic-gate printer(arg, " length %d", clen); 1344*7c478bd9Sstevel@tonic-gate break; 1345*7c478bd9Sstevel@tonic-gate case CI_PREDICTOR_2: 1346*7c478bd9Sstevel@tonic-gate printer(arg, "predictor-2"); 1347*7c478bd9Sstevel@tonic-gate if (clen != CILEN_PREDICTOR_2) 1348*7c478bd9Sstevel@tonic-gate printer(arg, " length %d", clen); 1349*7c478bd9Sstevel@tonic-gate break; 1350*7c478bd9Sstevel@tonic-gate #ifdef CI_STAC 1351*7c478bd9Sstevel@tonic-gate case CI_STAC: 1352*7c478bd9Sstevel@tonic-gate printer(arg, "Stac"); 1353*7c478bd9Sstevel@tonic-gate if (clen != CILEN_STAC) 1354*7c478bd9Sstevel@tonic-gate printer(arg, " length %d", clen); 1355*7c478bd9Sstevel@tonic-gate if (optlen >= CILEN_STAC) { 1356*7c478bd9Sstevel@tonic-gate GETSHORT(cishort, p); 1357*7c478bd9Sstevel@tonic-gate GETCHAR(cichar, p); 1358*7c478bd9Sstevel@tonic-gate printer(arg, " h%d/m%d", cishort, cichar); 1359*7c478bd9Sstevel@tonic-gate } 1360*7c478bd9Sstevel@tonic-gate break; 1361*7c478bd9Sstevel@tonic-gate #endif 1362*7c478bd9Sstevel@tonic-gate #ifdef CI_MPPC 1363*7c478bd9Sstevel@tonic-gate case CI_MPPC: 1364*7c478bd9Sstevel@tonic-gate /* There appears to be no good generic name for this one. */ 1365*7c478bd9Sstevel@tonic-gate if (optlen >= CILEN_MPPC) { 1366*7c478bd9Sstevel@tonic-gate GETLONG(cilong, p); 1367*7c478bd9Sstevel@tonic-gate if (!(cilong & MPPC_COMP)) { 1368*7c478bd9Sstevel@tonic-gate if (cilong & MPPC_MPPE) 1369*7c478bd9Sstevel@tonic-gate printer(arg, "MPPE"); 1370*7c478bd9Sstevel@tonic-gate else 1371*7c478bd9Sstevel@tonic-gate printer(arg, "MS-PPC?"); 1372*7c478bd9Sstevel@tonic-gate } else { 1373*7c478bd9Sstevel@tonic-gate if (cilong & MPPC_MPPE) 1374*7c478bd9Sstevel@tonic-gate printer(arg, "MPPC+MPPE"); 1375*7c478bd9Sstevel@tonic-gate else 1376*7c478bd9Sstevel@tonic-gate printer(arg, "MPPC"); 1377*7c478bd9Sstevel@tonic-gate } 1378*7c478bd9Sstevel@tonic-gate } else { 1379*7c478bd9Sstevel@tonic-gate printer(arg, "MS-?"); 1380*7c478bd9Sstevel@tonic-gate } 1381*7c478bd9Sstevel@tonic-gate if (clen != CILEN_STAC) 1382*7c478bd9Sstevel@tonic-gate printer(arg, " length %d", clen); 1383*7c478bd9Sstevel@tonic-gate break; 1384*7c478bd9Sstevel@tonic-gate #endif 1385*7c478bd9Sstevel@tonic-gate default: 1386*7c478bd9Sstevel@tonic-gate printer(arg, "typ%d len%d ", code, clen); 1387*7c478bd9Sstevel@tonic-gate break; 1388*7c478bd9Sstevel@tonic-gate } 1389*7c478bd9Sstevel@tonic-gate if (p < optend) { 1390*7c478bd9Sstevel@tonic-gate if (p+8 < optend) 1391*7c478bd9Sstevel@tonic-gate printer(arg, " %.8B ...", p); 1392*7c478bd9Sstevel@tonic-gate else 1393*7c478bd9Sstevel@tonic-gate printer(arg, " %.*B", optend-p, p); 1394*7c478bd9Sstevel@tonic-gate p = optend; 1395*7c478bd9Sstevel@tonic-gate } 1396*7c478bd9Sstevel@tonic-gate printer(arg, ">"); 1397*7c478bd9Sstevel@tonic-gate } 1398*7c478bd9Sstevel@tonic-gate break; 1399*7c478bd9Sstevel@tonic-gate 1400*7c478bd9Sstevel@tonic-gate case CODE_TERMACK: 1401*7c478bd9Sstevel@tonic-gate case CODE_TERMREQ: 1402*7c478bd9Sstevel@tonic-gate if (len > 0) { 1403*7c478bd9Sstevel@tonic-gate if (len == 2) { 1404*7c478bd9Sstevel@tonic-gate GETSHORT(cishort, p); 1405*7c478bd9Sstevel@tonic-gate printer(arg, " history %d", cishort); 1406*7c478bd9Sstevel@tonic-gate len = 0; 1407*7c478bd9Sstevel@tonic-gate } else if (*p >= ' ' && *p < 0x7f) { 1408*7c478bd9Sstevel@tonic-gate printer(arg, " "); 1409*7c478bd9Sstevel@tonic-gate print_string((char *)p, len, printer, arg); 1410*7c478bd9Sstevel@tonic-gate p += len; 1411*7c478bd9Sstevel@tonic-gate len = 0; 1412*7c478bd9Sstevel@tonic-gate } 1413*7c478bd9Sstevel@tonic-gate } 1414*7c478bd9Sstevel@tonic-gate break; 1415*7c478bd9Sstevel@tonic-gate } 1416*7c478bd9Sstevel@tonic-gate 1417*7c478bd9Sstevel@tonic-gate /* dump out the rest of the packet in hex */ 1418*7c478bd9Sstevel@tonic-gate if (len > 0) { 1419*7c478bd9Sstevel@tonic-gate if (len > 8) 1420*7c478bd9Sstevel@tonic-gate printer(arg, " %.8B ...", p); 1421*7c478bd9Sstevel@tonic-gate else 1422*7c478bd9Sstevel@tonic-gate printer(arg, " %.*B", len, p); 1423*7c478bd9Sstevel@tonic-gate p += len; 1424*7c478bd9Sstevel@tonic-gate } 1425*7c478bd9Sstevel@tonic-gate 1426*7c478bd9Sstevel@tonic-gate return p - p0; 1427*7c478bd9Sstevel@tonic-gate } 1428*7c478bd9Sstevel@tonic-gate 1429*7c478bd9Sstevel@tonic-gate /* 1430*7c478bd9Sstevel@tonic-gate * We have received a packet that the decompressor failed to 1431*7c478bd9Sstevel@tonic-gate * decompress. Here we would expect to issue a reset-request, but 1432*7c478bd9Sstevel@tonic-gate * Motorola has a patent on resetting the compressor as a result of 1433*7c478bd9Sstevel@tonic-gate * detecting an error in the decompressed data after decompression. 1434*7c478bd9Sstevel@tonic-gate * (See US patent 5,130,993; international patent publication number 1435*7c478bd9Sstevel@tonic-gate * WO 91/10289; Australian patent 73296/91.) 1436*7c478bd9Sstevel@tonic-gate * 1437*7c478bd9Sstevel@tonic-gate * So we ask the kernel whether the error was detected after 1438*7c478bd9Sstevel@tonic-gate * decompression; if it was, we take CCP down, thus disabling 1439*7c478bd9Sstevel@tonic-gate * compression :-(, otherwise we issue the reset-request. 1440*7c478bd9Sstevel@tonic-gate */ 1441*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 1442*7c478bd9Sstevel@tonic-gate static void 1443*7c478bd9Sstevel@tonic-gate ccp_datainput(unit, pkt, len) 1444*7c478bd9Sstevel@tonic-gate int unit; 1445*7c478bd9Sstevel@tonic-gate u_char *pkt; 1446*7c478bd9Sstevel@tonic-gate int len; 1447*7c478bd9Sstevel@tonic-gate { 1448*7c478bd9Sstevel@tonic-gate fsm *f; 1449*7c478bd9Sstevel@tonic-gate 1450*7c478bd9Sstevel@tonic-gate f = &ccp_fsm[unit]; 1451*7c478bd9Sstevel@tonic-gate if (f->state == OPENED) { 1452*7c478bd9Sstevel@tonic-gate if (ccp_fatal_error(unit)) { 1453*7c478bd9Sstevel@tonic-gate /* 1454*7c478bd9Sstevel@tonic-gate * Disable compression by taking CCP down. 1455*7c478bd9Sstevel@tonic-gate */ 1456*7c478bd9Sstevel@tonic-gate error("Lost compression sync: disabling compression"); 1457*7c478bd9Sstevel@tonic-gate ccp_close(unit, "Lost compression sync"); 1458*7c478bd9Sstevel@tonic-gate } else { 1459*7c478bd9Sstevel@tonic-gate /* 1460*7c478bd9Sstevel@tonic-gate * Send a reset-request to reset the peer's compressor, if 1461*7c478bd9Sstevel@tonic-gate * possible. We don't do anything if we are still waiting 1462*7c478bd9Sstevel@tonic-gate * for an acknowledgement to a previous reset-request (to 1463*7c478bd9Sstevel@tonic-gate * avoid flooding the peer). We reopen CCP if the peer 1464*7c478bd9Sstevel@tonic-gate * doesn't like hearing about CCP Reset-Request (Cisco 1465*7c478bd9Sstevel@tonic-gate * sends CCP Code-Reject for Reset-Request). (Reopen 1466*7c478bd9Sstevel@tonic-gate * automatically clears the flags and cancels the 1467*7c478bd9Sstevel@tonic-gate * timeout.) 1468*7c478bd9Sstevel@tonic-gate */ 1469*7c478bd9Sstevel@tonic-gate if (ccp_localstate[f->unit] & RREQ_REJECTED) { 1470*7c478bd9Sstevel@tonic-gate dbglog("reopening CCP to reset peer's compressor"); 1471*7c478bd9Sstevel@tonic-gate ccp_open(f->unit); 1472*7c478bd9Sstevel@tonic-gate } else if (ccp_localstate[f->unit] & RACK_PENDING) { 1473*7c478bd9Sstevel@tonic-gate /* Send another reset request; we're out of sequence. */ 1474*7c478bd9Sstevel@tonic-gate ccp_localstate[f->unit] |= RREQ_REPEAT; 1475*7c478bd9Sstevel@tonic-gate } else { 1476*7c478bd9Sstevel@tonic-gate dbglog("sending CCP Reset-Request to reset peer's compressor"); 1477*7c478bd9Sstevel@tonic-gate fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0); 1478*7c478bd9Sstevel@tonic-gate TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT); 1479*7c478bd9Sstevel@tonic-gate ccp_localstate[f->unit] |= RACK_PENDING; 1480*7c478bd9Sstevel@tonic-gate } 1481*7c478bd9Sstevel@tonic-gate } 1482*7c478bd9Sstevel@tonic-gate } 1483*7c478bd9Sstevel@tonic-gate } 1484*7c478bd9Sstevel@tonic-gate 1485*7c478bd9Sstevel@tonic-gate /* 1486*7c478bd9Sstevel@tonic-gate * Timeout waiting for reset-ack. 1487*7c478bd9Sstevel@tonic-gate */ 1488*7c478bd9Sstevel@tonic-gate static void 1489*7c478bd9Sstevel@tonic-gate ccp_rack_timeout(arg) 1490*7c478bd9Sstevel@tonic-gate void *arg; 1491*7c478bd9Sstevel@tonic-gate { 1492*7c478bd9Sstevel@tonic-gate fsm *f = arg; 1493*7c478bd9Sstevel@tonic-gate 1494*7c478bd9Sstevel@tonic-gate /* Timeout; no longer pending. */ 1495*7c478bd9Sstevel@tonic-gate ccp_localstate[f->unit] &= ~RACK_PENDING; 1496*7c478bd9Sstevel@tonic-gate 1497*7c478bd9Sstevel@tonic-gate /* Frankly, it's a coding flaw if this occurs. */ 1498*7c478bd9Sstevel@tonic-gate if (f->state != OPENED) 1499*7c478bd9Sstevel@tonic-gate return; 1500*7c478bd9Sstevel@tonic-gate 1501*7c478bd9Sstevel@tonic-gate if (ccp_localstate[f->unit] & RREQ_IGNORED) { 1502*7c478bd9Sstevel@tonic-gate info("peer ignored our CCP Reset-Request twice; reopen instead"); 1503*7c478bd9Sstevel@tonic-gate ccp_localstate[f->unit] = 1504*7c478bd9Sstevel@tonic-gate (ccp_localstate[f->unit] & ~RREQ_IGNORED) | RREQ_REJECTED; 1505*7c478bd9Sstevel@tonic-gate ccp_open(f->unit); 1506*7c478bd9Sstevel@tonic-gate } else if (ccp_localstate[f->unit] & RREQ_REPEAT) { 1507*7c478bd9Sstevel@tonic-gate dbglog("sending another CCP Reset-Request on timeout"); 1508*7c478bd9Sstevel@tonic-gate fsm_sdata(f, CCP_RESETREQ, f->reqid, NULL, 0); 1509*7c478bd9Sstevel@tonic-gate TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT); 1510*7c478bd9Sstevel@tonic-gate ccp_localstate[f->unit] = 1511*7c478bd9Sstevel@tonic-gate (ccp_localstate[f->unit] & ~RREQ_REPEAT) | RREQ_IGNORED | 1512*7c478bd9Sstevel@tonic-gate RACK_PENDING; 1513*7c478bd9Sstevel@tonic-gate } else { 1514*7c478bd9Sstevel@tonic-gate dbglog("timeout waiting for CCP Reset-Ack; hope for the best"); 1515*7c478bd9Sstevel@tonic-gate ccp_localstate[f->unit] |= RREQ_IGNORED; 1516*7c478bd9Sstevel@tonic-gate } 1517*7c478bd9Sstevel@tonic-gate } 1518