ccp.c revision 8ad0dd2a5c5f23cd210aedba72a43e48026e7436
18ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
28ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp.c - PPP Compression Control Protocol.
38ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
48ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved.
58ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
68ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Redistribution and use in source and binary forms, with or without
78ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * modification, are permitted provided that the following conditions
88ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * are met:
98ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 2. The name(s) of the authors of this software must not be used to
148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    endorse or promote products derived from this software without
158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    prior written permission.
168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 3. Redistributions of any form whatsoever must retain the following
188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    acknowledgment:
198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    "This product includes software developed by Paul Mackerras
208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *     <paulus@samba.org>".
218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define RCSID	"$Id: ccp.c,v 1.48 2004/11/13 02:28:15 paulus Exp $"
328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdlib.h>
348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <string.h>
358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "pppd.h"
378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "fsm.h"
388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "ccp.h"
398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <net/ppp-comp.h>
408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "chap_ms.h"	/* mppe_xxxx_key, mppe_keys_set */
438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "lcp.h"	/* lcp_close(), lcp_fsm */
448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic const char rcsid[] = RCSID;
478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Unfortunately there is a bug in zlib which means that using a
508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * size of 8 (window size = 256) for Deflate compression will cause
518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * buffer overruns and kernel crashes in the deflate module.
528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Until this is fixed we only accept sizes in the range 9 .. 15.
538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Thanks to James Carlson for pointing this out.
548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define DEFLATE_MIN_WORKS	9
568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Command-line options.
598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int setbsdcomp __P((char **));
618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int setdeflate __P((char **));
628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char bsd_value[8];
638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char deflate_value[8];
648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Option variables.
678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectbool refuse_mppe_stateful = 1;		/* Allow stateful mode? */
708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic option_t ccp_option_list[] = {
738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "noccp", o_bool, &ccp_protent.enabled_flag,
748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Disable CCP negotiation" },
758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "-ccp", o_bool, &ccp_protent.enabled_flag,
768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Disable CCP negotiation", OPT_ALIAS },
778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "bsdcomp", o_special, (void *)setbsdcomp,
798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Request BSD-Compress packet compression",
808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, bsd_value },
818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "nobsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress,
828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "don't allow BSD-Compress", OPT_PRIOSUB | OPT_A2CLR,
838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      &ccp_allowoptions[0].bsd_compress },
848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "-bsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress,
858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "don't allow BSD-Compress", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      &ccp_allowoptions[0].bsd_compress },
878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "deflate", o_special, (void *)setdeflate,
898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "request Deflate compression",
908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, deflate_value },
918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "nodeflate", o_bool, &ccp_wantoptions[0].deflate,
928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "don't allow Deflate compression", OPT_PRIOSUB | OPT_A2CLR,
938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      &ccp_allowoptions[0].deflate },
948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "-deflate", o_bool, &ccp_wantoptions[0].deflate,
958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "don't allow Deflate compression", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      &ccp_allowoptions[0].deflate },
978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "nodeflatedraft", o_bool, &ccp_wantoptions[0].deflate_draft,
998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "don't use draft deflate #", OPT_A2COPY,
1008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      &ccp_allowoptions[0].deflate_draft },
1018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "predictor1", o_bool, &ccp_wantoptions[0].predictor_1,
1038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "request Predictor-1", OPT_PRIO | 1 },
1048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "nopredictor1", o_bool, &ccp_wantoptions[0].predictor_1,
1058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "don't allow Predictor-1", OPT_PRIOSUB | OPT_A2CLR,
1068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      &ccp_allowoptions[0].predictor_1 },
1078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "-predictor1", o_bool, &ccp_wantoptions[0].predictor_1,
1088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "don't allow Predictor-1", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
1098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      &ccp_allowoptions[0].predictor_1 },
1108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
1128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* MPPE options are symmetrical ... we only set wantoptions here */
1138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "require-mppe", o_bool, &ccp_wantoptions[0].mppe,
1148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "require MPPE encryption",
1158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 },
1168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "+mppe", o_bool, &ccp_wantoptions[0].mppe,
1178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "require MPPE encryption",
1188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_ALIAS | OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 },
1198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "nomppe", o_bool, &ccp_wantoptions[0].mppe,
1208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "don't allow MPPE encryption", OPT_PRIO },
1218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "-mppe", o_bool, &ccp_wantoptions[0].mppe,
1228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "don't allow MPPE encryption", OPT_ALIAS | OPT_PRIO },
1238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* We use ccp_allowoptions[0].mppe as a junk var ... it is reset later */
1258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "require-mppe-40", o_bool, &ccp_allowoptions[0].mppe,
1268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40,
1278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      &ccp_wantoptions[0].mppe },
1288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "+mppe-40", o_bool, &ccp_allowoptions[0].mppe,
1298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40,
1308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      &ccp_wantoptions[0].mppe },
1318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "nomppe-40", o_bool, &ccp_allowoptions[0].mppe,
1328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "don't allow MPPE 40-bit encryption",
1338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, &ccp_wantoptions[0].mppe },
1348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "-mppe-40", o_bool, &ccp_allowoptions[0].mppe,
1358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "don't allow MPPE 40-bit encryption",
1368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40,
1378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      &ccp_wantoptions[0].mppe },
1388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "require-mppe-128", o_bool, &ccp_allowoptions[0].mppe,
1408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "require MPPE 128-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_128,
1418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      &ccp_wantoptions[0].mppe },
1428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "+mppe-128", o_bool, &ccp_allowoptions[0].mppe,
1438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "require MPPE 128-bit encryption",
1448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_ALIAS | OPT_PRIO | OPT_A2OR | MPPE_OPT_128,
1458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      &ccp_wantoptions[0].mppe },
1468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "nomppe-128", o_bool, &ccp_allowoptions[0].mppe,
1478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "don't allow MPPE 128-bit encryption",
1488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, &ccp_wantoptions[0].mppe },
1498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "-mppe-128", o_bool, &ccp_allowoptions[0].mppe,
1508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "don't allow MPPE 128-bit encryption",
1518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128,
1528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      &ccp_wantoptions[0].mppe },
1538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* strange one; we always request stateless, but will we allow stateful? */
1558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "mppe-stateful", o_bool, &refuse_mppe_stateful,
1568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "allow MPPE stateful mode", OPT_PRIO },
1578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "nomppe-stateful", o_bool, &refuse_mppe_stateful,
1588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "disallow MPPE stateful mode", OPT_PRIO | 1 },
1598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* MPPE */
1608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { NULL }
1628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
1638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
1658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Protocol entry points from main code.
1668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
1678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ccp_init __P((int unit));
1688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ccp_open __P((int unit));
1698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ccp_close __P((int unit, char *));
1708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ccp_lowerup __P((int unit));
1718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ccp_lowerdown __P((int));
1728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ccp_input __P((int unit, u_char *pkt, int len));
1738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ccp_protrej __P((int unit));
1748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  ccp_printpkt __P((u_char *pkt, int len,
1758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			      void (*printer) __P((void *, char *, ...)),
1768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			      void *arg));
1778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ccp_datainput __P((int unit, u_char *pkt, int len));
1788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstruct protent ccp_protent = {
1808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    PPP_CCP,
1818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_init,
1828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_input,
1838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_protrej,
1848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_lowerup,
1858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_lowerdown,
1868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_open,
1878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_close,
1888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_printpkt,
1898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_datainput,
1908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    1,
1918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    "CCP",
1928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    "Compressed",
1938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_option_list,
1948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL,
1958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL,
1968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL
1978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
1988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectfsm ccp_fsm[NUM_PPP];
2008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_options ccp_wantoptions[NUM_PPP];	/* what to request the peer to use */
2018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_options ccp_gotoptions[NUM_PPP];	/* what the peer agreed to do */
2028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_options ccp_allowoptions[NUM_PPP];	/* what we'll agree to do */
2038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_options ccp_hisoptions[NUM_PPP];	/* what we agreed to do */
2048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Callbacks for fsm code.
2078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
2088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ccp_resetci __P((fsm *));
2098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  ccp_cilen __P((fsm *));
2108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ccp_addci __P((fsm *, u_char *, int *));
2118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  ccp_ackci __P((fsm *, u_char *, int));
2128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  ccp_nakci __P((fsm *, u_char *, int, int));
2138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  ccp_rejci __P((fsm *, u_char *, int));
2148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  ccp_reqci __P((fsm *, u_char *, int *, int));
2158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ccp_up __P((fsm *));
2168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ccp_down __P((fsm *));
2178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  ccp_extcode __P((fsm *, int, int, u_char *, int));
2188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ccp_rack_timeout __P((void *));
2198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char *method_name __P((ccp_options *, ccp_options *));
2208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic fsm_callbacks ccp_callbacks = {
2228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_resetci,
2238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_cilen,
2248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_addci,
2258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_ackci,
2268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_nakci,
2278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_rejci,
2288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_reqci,
2298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_up,
2308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_down,
2318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL,
2328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL,
2338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL,
2348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL,
2358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_extcode,
2368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    "CCP"
2378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
2388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Do we want / did we get any compression?
2418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
2428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ANY_COMPRESS(opt)	((opt).deflate || (opt).bsd_compress \
2438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 || (opt).predictor_1 || (opt).predictor_2 \
2448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 || (opt).mppe)
2458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Local state (mainly for handling reset-reqs and reset-acks).
2488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
2498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int ccp_localstate[NUM_PPP];
2508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define RACK_PENDING	1	/* waiting for reset-ack */
2518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define RREQ_REPEAT	2	/* send another reset-req if no reset-ack */
2528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define RACKTIMEOUT	1	/* second */
2548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int all_rejected[NUM_PPP];	/* we rejected all peer's options */
2568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Option parsing.
2598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
2608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
2618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsetbsdcomp(argv)
2628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char **argv;
2638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
2648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int rbits, abits;
2658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *str, *endp;
2668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    str = *argv;
2688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    abits = rbits = strtol(str, &endp, 0);
2698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (endp != str && *endp == ',') {
2708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	str = endp + 1;
2718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	abits = strtol(str, &endp, 0);
2728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
2738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (*endp != 0 || endp == str) {
2748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	option_error("invalid parameter '%s' for bsdcomp option", *argv);
2758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
2768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
2778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if ((rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS))
2788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	|| (abits != 0 && (abits < BSD_MIN_BITS || abits > BSD_MAX_BITS))) {
2798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	option_error("bsdcomp option values must be 0 or %d .. %d",
2808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     BSD_MIN_BITS, BSD_MAX_BITS);
2818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
2828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
2838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rbits > 0) {
2848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ccp_wantoptions[0].bsd_compress = 1;
2858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ccp_wantoptions[0].bsd_bits = rbits;
2868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else
2878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ccp_wantoptions[0].bsd_compress = 0;
2888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (abits > 0) {
2898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ccp_allowoptions[0].bsd_compress = 1;
2908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ccp_allowoptions[0].bsd_bits = abits;
2918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else
2928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ccp_allowoptions[0].bsd_compress = 0;
2938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    slprintf(bsd_value, sizeof(bsd_value),
2948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     rbits == abits? "%d": "%d,%d", rbits, abits);
2958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
2978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
2988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
3008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsetdeflate(argv)
3018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char **argv;
3028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
3038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int rbits, abits;
3048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *str, *endp;
3058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    str = *argv;
3078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    abits = rbits = strtol(str, &endp, 0);
3088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (endp != str && *endp == ',') {
3098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	str = endp + 1;
3108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	abits = strtol(str, &endp, 0);
3118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (*endp != 0 || endp == str) {
3138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	option_error("invalid parameter '%s' for deflate option", *argv);
3148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
3158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if ((rbits != 0 && (rbits < DEFLATE_MIN_SIZE || rbits > DEFLATE_MAX_SIZE))
3178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	|| (abits != 0 && (abits < DEFLATE_MIN_SIZE
3188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			  || abits > DEFLATE_MAX_SIZE))) {
3198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	option_error("deflate option values must be 0 or %d .. %d",
3208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE);
3218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
3228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rbits == DEFLATE_MIN_SIZE || abits == DEFLATE_MIN_SIZE) {
3248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (rbits == DEFLATE_MIN_SIZE)
3258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    rbits = DEFLATE_MIN_WORKS;
3268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (abits == DEFLATE_MIN_SIZE)
3278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    abits = DEFLATE_MIN_WORKS;
3288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("deflate option value of %d changed to %d to avoid zlib bug",
3298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     DEFLATE_MIN_SIZE, DEFLATE_MIN_WORKS);
3308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rbits > 0) {
3328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ccp_wantoptions[0].deflate = 1;
3338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ccp_wantoptions[0].deflate_size = rbits;
3348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else
3358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ccp_wantoptions[0].deflate = 0;
3368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (abits > 0) {
3378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ccp_allowoptions[0].deflate = 1;
3388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ccp_allowoptions[0].deflate_size = abits;
3398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else
3408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ccp_allowoptions[0].deflate = 0;
3418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    slprintf(deflate_value, sizeof(deflate_value),
3428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     rbits == abits? "%d": "%d,%d", rbits, abits);
3438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
3458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
3468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
3488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp_init - initialize CCP.
3498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
3508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
3518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_init(unit)
3528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
3538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
3548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f = &ccp_fsm[unit];
3558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    f->unit = unit;
3578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    f->protocol = PPP_CCP;
3588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    f->callbacks = &ccp_callbacks;
3598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_init(f);
3608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&ccp_wantoptions[unit],  0, sizeof(ccp_options));
3628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&ccp_gotoptions[unit],   0, sizeof(ccp_options));
3638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&ccp_allowoptions[unit], 0, sizeof(ccp_options));
3648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&ccp_hisoptions[unit],   0, sizeof(ccp_options));
3658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_wantoptions[0].deflate = 1;
3678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_wantoptions[0].deflate_size = DEFLATE_MAX_SIZE;
3688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_wantoptions[0].deflate_correct = 1;
3698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_wantoptions[0].deflate_draft = 1;
3708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_allowoptions[0].deflate = 1;
3718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_allowoptions[0].deflate_size = DEFLATE_MAX_SIZE;
3728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_allowoptions[0].deflate_correct = 1;
3738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_allowoptions[0].deflate_draft = 1;
3748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_wantoptions[0].bsd_compress = 1;
3768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_wantoptions[0].bsd_bits = BSD_MAX_BITS;
3778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_allowoptions[0].bsd_compress = 1;
3788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_allowoptions[0].bsd_bits = BSD_MAX_BITS;
3798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_allowoptions[0].predictor_1 = 1;
3818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
3828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
3848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp_open - CCP is allowed to come up.
3858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
3868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
3878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_open(unit)
3888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
3898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
3908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f = &ccp_fsm[unit];
3918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->state != OPENED)
3938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ccp_flags_set(unit, 1, 0);
3948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
3968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Find out which compressors the kernel supports before
3978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * deciding whether to open in silent mode.
3988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
3998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_resetci(f);
4008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!ANY_COMPRESS(ccp_gotoptions[unit]))
4018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	f->flags |= OPT_SILENT;
4028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_open(f);
4048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp_close - Terminate CCP.
4088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
4108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_close(unit, reason)
4118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
4128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *reason;
4138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_flags_set(unit, 0, 0);
4158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_close(&ccp_fsm[unit], reason);
4168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp_lowerup - we may now transmit CCP packets.
4208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
4228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_lowerup(unit)
4238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
4248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_lowerup(&ccp_fsm[unit]);
4268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp_lowerdown - we may not transmit CCP packets.
4308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
4328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_lowerdown(unit)
4338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
4348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_lowerdown(&ccp_fsm[unit]);
4368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp_input - process a received CCP packet.
4408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
4428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_input(unit, p, len)
4438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
4448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
4458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
4468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f = &ccp_fsm[unit];
4488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int oldstate;
4498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
4518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Check for a terminate-request so we can print a message.
4528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
4538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    oldstate = f->state;
4548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_input(f, p, len);
4558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (oldstate == OPENED && p[0] == TERMREQ && f->state != OPENED) {
4568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	notice("Compression disabled by peer.");
4578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
4588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ccp_gotoptions[unit].mppe) {
4598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("MPPE disabled, closing LCP");
4608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    lcp_close(unit, "MPPE disabled by peer");
4618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
4628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
4638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
4648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
4668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If we get a terminate-ack and we're not asking for compression,
4678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * close CCP.
4688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
4698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (oldstate == REQSENT && p[0] == TERMACK
4708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& !ANY_COMPRESS(ccp_gotoptions[unit]))
4718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ccp_close(unit, "No compression negotiated");
4728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Handle a CCP-specific code.
4768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
4788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_extcode(f, code, id, p, len)
4798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
4808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int code, id;
4818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
4828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
4838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    switch (code) {
4858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CCP_RESETREQ:
4868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (f->state != OPENED)
4878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
4888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* send a reset-ack, which the transmitter will see and
4898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	   reset its compression state. */
4908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fsm_sdata(f, CCP_RESETACK, id, NULL, 0);
4918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
4928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CCP_RESETACK:
4948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ccp_localstate[f->unit] & RACK_PENDING && id == f->reqid) {
4958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ccp_localstate[f->unit] &= ~(RACK_PENDING | RREQ_REPEAT);
4968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    UNTIMEOUT(ccp_rack_timeout, f);
4978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
4988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
4998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    default:
5018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
5028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
5038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
5058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
5068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
5088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp_protrej - peer doesn't talk CCP.
5098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
5108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
5118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_protrej(unit)
5128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
5138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
5148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_flags_set(unit, 0, 0);
5158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_lowerdown(&ccp_fsm[unit]);
5168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
5188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ccp_gotoptions[unit].mppe) {
5198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("MPPE required but peer negotiation failed");
5208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	lcp_close(unit, "MPPE required but peer negotiation failed");
5218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
5228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
5238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
5258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
5278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp_resetci - initialize at start of negotiation.
5288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
5298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
5308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_resetci(f)
5318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
5328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
5338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_options *go = &ccp_gotoptions[f->unit];
5348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char opt_buf[CCP_MAX_OPTION_LENGTH];
5358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    *go = ccp_wantoptions[f->unit];
5378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    all_rejected[f->unit] = 0;
5388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
5408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->mppe) {
5418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ccp_options *ao = &ccp_allowoptions[f->unit];
5428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int auth_mschap_bits = auth_done[f->unit];
5438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int numbits;
5448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
5468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Start with a basic sanity check: mschap[v2] auth must be in
5478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * exactly one direction.  RFC 3079 says that the keys are
5488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * 'derived from the credentials of the peer that initiated the call',
5498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * however the PPP protocol doesn't have such a concept, and pppd
5508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * cannot get this info externally.  Instead we do the best we can.
5518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * NB: If MPPE is required, all other compression opts are invalid.
5528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 *     So, we return right away if we can't do it.
5538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
5548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Leave only the mschap auth bits set */
5568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	auth_mschap_bits &= (CHAP_MS_WITHPEER  | CHAP_MS_PEER |
5578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			     CHAP_MS2_WITHPEER | CHAP_MS2_PEER);
5588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Count the mschap auths */
5598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	auth_mschap_bits >>= CHAP_MS_SHIFT;
5608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	numbits = 0;
5618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	do {
5628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    numbits += auth_mschap_bits & 1;
5638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    auth_mschap_bits >>= 1;
5648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} while (auth_mschap_bits);
5658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (numbits > 1) {
5668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("MPPE required, but auth done in both directions.");
5678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    lcp_close(f->unit, "MPPE required but not available");
5688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return;
5698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
5708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!numbits) {
5718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("MPPE required, but MS-CHAP[v2] auth not performed.");
5728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    lcp_close(f->unit, "MPPE required but not available");
5738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return;
5748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
5758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* A plugin (eg radius) may not have obtained key material. */
5778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!mppe_keys_set) {
5788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("MPPE required, but keys are not available.  "
5798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		  "Possible plugin problem?");
5808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    lcp_close(f->unit, "MPPE required but not available");
5818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return;
5828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
5838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* LM auth not supported for MPPE */
5858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (auth_done[f->unit] & (CHAP_MS_WITHPEER | CHAP_MS_PEER)) {
5868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* This might be noise */
5878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->mppe & MPPE_OPT_40) {
5888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		notice("Disabling 40-bit MPPE; MS-CHAP LM not supported");
5898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		go->mppe &= ~MPPE_OPT_40;
5908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ccp_wantoptions[f->unit].mppe &= ~MPPE_OPT_40;
5918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
5928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
5938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Last check: can we actually negotiate something? */
5958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!(go->mppe & (MPPE_OPT_40 | MPPE_OPT_128))) {
5968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* Could be misconfig, could be 40-bit disabled above. */
5978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("MPPE required, but both 40-bit and 128-bit disabled.");
5988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    lcp_close(f->unit, "MPPE required but not available");
5998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return;
6008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
6018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* sync options */
6038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ao->mppe = go->mppe;
6048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* MPPE is not compatible with other compression types */
6058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ao->bsd_compress = go->bsd_compress = 0;
6068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ao->predictor_1  = go->predictor_1  = 0;
6078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ao->predictor_2  = go->predictor_2  = 0;
6088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ao->deflate      = go->deflate      = 0;
6098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* MPPE */
6118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
6138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Check whether the kernel knows about the various
6148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * compression methods we might request.
6158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
6168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
6178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->mppe) {
6188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	opt_buf[0] = CI_MPPE;
6198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	opt_buf[1] = CILEN_MPPE;
6208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
6218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Key material unimportant here. */
6228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0) {
6238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("MPPE required, but kernel has no support.");
6248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    lcp_close(f->unit, "MPPE required but not available");
6258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
6268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
6288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->bsd_compress) {
6298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	opt_buf[0] = CI_BSD_COMPRESS;
6308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	opt_buf[1] = CILEN_BSD_COMPRESS;
6318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	opt_buf[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, BSD_MIN_BITS);
6328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ccp_test(f->unit, opt_buf, CILEN_BSD_COMPRESS, 0) <= 0)
6338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    go->bsd_compress = 0;
6348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->deflate) {
6368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (go->deflate_correct) {
6378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    opt_buf[0] = CI_DEFLATE;
6388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    opt_buf[1] = CILEN_DEFLATE;
6398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_WORKS);
6408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    opt_buf[3] = DEFLATE_CHK_SEQUENCE;
6418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0)
6428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		go->deflate_correct = 0;
6438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
6448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (go->deflate_draft) {
6458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    opt_buf[0] = CI_DEFLATE_DRAFT;
6468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    opt_buf[1] = CILEN_DEFLATE;
6478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_WORKS);
6488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    opt_buf[3] = DEFLATE_CHK_SEQUENCE;
6498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0)
6508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		go->deflate_draft = 0;
6518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
6528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!go->deflate_correct && !go->deflate_draft)
6538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    go->deflate = 0;
6548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->predictor_1) {
6568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	opt_buf[0] = CI_PREDICTOR_1;
6578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	opt_buf[1] = CILEN_PREDICTOR_1;
6588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_1, 0) <= 0)
6598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    go->predictor_1 = 0;
6608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->predictor_2) {
6628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	opt_buf[0] = CI_PREDICTOR_2;
6638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	opt_buf[1] = CILEN_PREDICTOR_2;
6648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_2, 0) <= 0)
6658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    go->predictor_2 = 0;
6668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
6688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
6708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp_cilen - Return total length of our configuration info.
6718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
6728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
6738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_cilen(f)
6748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
6758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
6768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_options *go = &ccp_gotoptions[f->unit];
6778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return (go->bsd_compress? CILEN_BSD_COMPRESS: 0)
6798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	+ (go->deflate? CILEN_DEFLATE: 0)
6808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	+ (go->predictor_1? CILEN_PREDICTOR_1: 0)
6818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	+ (go->predictor_2? CILEN_PREDICTOR_2: 0)
6828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	+ (go->mppe? CILEN_MPPE: 0);
6838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
6848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
6868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp_addci - put our requests in a packet.
6878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
6888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
6898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_addci(f, p, lenp)
6908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
6918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
6928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int *lenp;
6938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
6948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int res;
6958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_options *go = &ccp_gotoptions[f->unit];
6968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p0 = p;
6978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
6998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Add the compression types that we can receive, in decreasing
7008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * preference order.  Get the kernel to allocate the first one
7018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * in case it gets Acked.
7028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
7038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
7048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->mppe) {
7058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN];
7068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] = opt_buf[0] = CI_MPPE;
7088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] = opt_buf[1] = CILEN_MPPE;
7098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	MPPE_OPTS_TO_CI(go->mppe, &p[2]);
7108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
7118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	BCOPY(mppe_recv_key, &opt_buf[CILEN_MPPE], MPPE_MAX_KEY_LEN);
7128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	res = ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0);
7138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (res > 0)
7148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p += CILEN_MPPE;
7158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	else
7168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* This shouldn't happen, we've already tested it! */
7178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    lcp_close(f->unit, "MPPE required but not available in kernel");
7188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
7208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->deflate) {
7218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] = go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT;
7228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] = CILEN_DEFLATE;
7238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[2] = DEFLATE_MAKE_OPT(go->deflate_size);
7248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[3] = DEFLATE_CHK_SEQUENCE;
7258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (p != p0) {
7268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p += CILEN_DEFLATE;
7278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else {
7288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    for (;;) {
7298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (go->deflate_size < DEFLATE_MIN_WORKS) {
7308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    go->deflate = 0;
7318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
7328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
7338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		res = ccp_test(f->unit, p, CILEN_DEFLATE, 0);
7348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (res > 0) {
7358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += CILEN_DEFLATE;
7368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
7378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} else if (res < 0) {
7388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    go->deflate = 0;
7398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
7408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
7418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		--go->deflate_size;
7428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		p[2] = DEFLATE_MAKE_OPT(go->deflate_size);
7438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
7448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
7458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (p != p0 && go->deflate_correct && go->deflate_draft) {
7468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p[0] = CI_DEFLATE_DRAFT;
7478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p[1] = CILEN_DEFLATE;
7488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p[2] = p[2 - CILEN_DEFLATE];
7498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p[3] = DEFLATE_CHK_SEQUENCE;
7508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p += CILEN_DEFLATE;
7518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
7528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->bsd_compress) {
7548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] = CI_BSD_COMPRESS;
7558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] = CILEN_BSD_COMPRESS;
7568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits);
7578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (p != p0) {
7588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p += CILEN_BSD_COMPRESS;	/* not the first option */
7598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else {
7608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    for (;;) {
7618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (go->bsd_bits < BSD_MIN_BITS) {
7628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    go->bsd_compress = 0;
7638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
7648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
7658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 0);
7668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (res > 0) {
7678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += CILEN_BSD_COMPRESS;
7688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
7698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} else if (res < 0) {
7708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    go->bsd_compress = 0;
7718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
7728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
7738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		--go->bsd_bits;
7748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits);
7758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
7768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
7778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* XXX Should Predictor 2 be preferable to Predictor 1? */
7798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->predictor_1) {
7808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] = CI_PREDICTOR_1;
7818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] = CILEN_PREDICTOR_1;
7828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_1, 0) <= 0) {
7838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    go->predictor_1 = 0;
7848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else {
7858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p += CILEN_PREDICTOR_1;
7868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
7878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->predictor_2) {
7898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] = CI_PREDICTOR_2;
7908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] = CILEN_PREDICTOR_2;
7918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_2, 0) <= 0) {
7928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    go->predictor_2 = 0;
7938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else {
7948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p += CILEN_PREDICTOR_2;
7958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
7968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    go->method = (p > p0)? p0[0]: -1;
7998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    *lenp = p - p0;
8018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
8028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
8048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp_ackci - process a received configure-ack, and return
8058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 1 iff the packet was OK.
8068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
8078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
8088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_ackci(f, p, len)
8098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
8108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
8118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
8128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
8138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_options *go = &ccp_gotoptions[f->unit];
8148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p0 = p;
8158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
8178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->mppe) {
8188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char opt_buf[CILEN_MPPE];
8198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	opt_buf[0] = CI_MPPE;
8218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	opt_buf[1] = CILEN_MPPE;
8228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
8238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len < CILEN_MPPE || memcmp(opt_buf, p, CILEN_MPPE))
8248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 0;
8258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p += CILEN_MPPE;
8268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_MPPE;
8278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* XXX Cope with first/fast ack */
8288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len == 0)
8298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 1;
8308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
8328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->deflate) {
8338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len < CILEN_DEFLATE
8348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    || p[0] != (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
8358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    || p[1] != CILEN_DEFLATE
8368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    || p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
8378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    || p[3] != DEFLATE_CHK_SEQUENCE)
8388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 0;
8398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p += CILEN_DEFLATE;
8408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_DEFLATE;
8418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* XXX Cope with first/fast ack */
8428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len == 0)
8438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 1;
8448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (go->deflate_correct && go->deflate_draft) {
8458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (len < CILEN_DEFLATE
8468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		|| p[0] != CI_DEFLATE_DRAFT
8478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		|| p[1] != CILEN_DEFLATE
8488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		|| p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
8498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		|| p[3] != DEFLATE_CHK_SEQUENCE)
8508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return 0;
8518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p += CILEN_DEFLATE;
8528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    len -= CILEN_DEFLATE;
8538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
8548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->bsd_compress) {
8568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len < CILEN_BSD_COMPRESS
8578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    || p[0] != CI_BSD_COMPRESS || p[1] != CILEN_BSD_COMPRESS
8588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    || p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits))
8598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 0;
8608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p += CILEN_BSD_COMPRESS;
8618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_BSD_COMPRESS;
8628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* XXX Cope with first/fast ack */
8638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (p == p0 && len == 0)
8648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 1;
8658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->predictor_1) {
8678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len < CILEN_PREDICTOR_1
8688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    || p[0] != CI_PREDICTOR_1 || p[1] != CILEN_PREDICTOR_1)
8698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 0;
8708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p += CILEN_PREDICTOR_1;
8718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_PREDICTOR_1;
8728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* XXX Cope with first/fast ack */
8738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (p == p0 && len == 0)
8748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 1;
8758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->predictor_2) {
8778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len < CILEN_PREDICTOR_2
8788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    || p[0] != CI_PREDICTOR_2 || p[1] != CILEN_PREDICTOR_2)
8798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 0;
8808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p += CILEN_PREDICTOR_2;
8818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_PREDICTOR_2;
8828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* XXX Cope with first/fast ack */
8838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (p == p0 && len == 0)
8848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 1;
8858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (len != 0)
8888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
8898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
8908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
8918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
8938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp_nakci - process received configure-nak.
8948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Returns 1 iff the nak was OK.
8958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
8968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
8978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_nakci(f, p, len, treat_as_reject)
8988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
8998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
9008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
9018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
9028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_options *go = &ccp_gotoptions[f->unit];
9038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_options no;		/* options we've seen already */
9048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_options try;		/* options to ask for next time */
9058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&no, 0, sizeof(no));
9078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    try = *go;
9088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
9108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->mppe && len >= CILEN_MPPE
9118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
9128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.mppe = 1;
9138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
9148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Peer wants us to use a different strength or other setting.
9158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Fail if we aren't willing to use his suggestion.
9168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
9178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	MPPE_CI_TO_OPTS(&p[2], try.mppe);
9188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((try.mppe & MPPE_OPT_STATEFUL) && refuse_mppe_stateful) {
9198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Refusing MPPE stateful mode offered by peer");
9208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    try.mppe = 0;
9218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else if (((go->mppe | MPPE_OPT_STATEFUL) & try.mppe) != try.mppe) {
9228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* Peer must have set options we didn't request (suggest) */
9238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    try.mppe = 0;
9248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
9258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!try.mppe) {
9278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("MPPE required but peer negotiation failed");
9288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    lcp_close(f->unit, "MPPE required but peer negotiation failed");
9298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
9308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* MPPE */
9328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->deflate && len >= CILEN_DEFLATE
9338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
9348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& p[1] == CILEN_DEFLATE) {
9358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.deflate = 1;
9368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
9378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Peer wants us to use a different code size or something.
9388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Stop asking for Deflate if we don't understand his suggestion.
9398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
9408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL
9418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    || DEFLATE_SIZE(p[2]) < DEFLATE_MIN_WORKS
9428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    || p[3] != DEFLATE_CHK_SEQUENCE)
9438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    try.deflate = 0;
9448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	else if (DEFLATE_SIZE(p[2]) < go->deflate_size)
9458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    try.deflate_size = DEFLATE_SIZE(p[2]);
9468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p += CILEN_DEFLATE;
9478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_DEFLATE;
9488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (go->deflate_correct && go->deflate_draft
9498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE_DRAFT
9508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    && p[1] == CILEN_DEFLATE) {
9518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p += CILEN_DEFLATE;
9528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    len -= CILEN_DEFLATE;
9538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
9548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->bsd_compress && len >= CILEN_BSD_COMPRESS
9578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) {
9588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.bsd_compress = 1;
9598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
9608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Peer wants us to use a different number of bits
9618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * or a different version.
9628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
9638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION)
9648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    try.bsd_compress = 0;
9658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	else if (BSD_NBITS(p[2]) < go->bsd_bits)
9668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    try.bsd_bits = BSD_NBITS(p[2]);
9678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p += CILEN_BSD_COMPRESS;
9688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_BSD_COMPRESS;
9698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
9728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Predictor-1 and 2 have no options, so they can't be Naked.
9738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     *
9748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * There may be remaining options but we ignore them.
9758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
9768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->state != OPENED)
9788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	*go = try;
9798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
9808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
9818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
9838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp_rejci - reject some of our suggested compression methods.
9848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
9858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
9868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_rejci(f, p, len)
9878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
9888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
9898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
9908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
9918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_options *go = &ccp_gotoptions[f->unit];
9928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_options try;		/* options to request next time */
9938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    try = *go;
9958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
9978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Cope with empty configure-rejects by ceasing to send
9988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * configure-requests.
9998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
10008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (len == 0 && all_rejected[f->unit])
10018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
10028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
10048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->mppe && len >= CILEN_MPPE
10058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
10068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("MPPE required but peer refused");
10078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	lcp_close(f->unit, "MPPE required but peer refused");
10088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p += CILEN_MPPE;
10098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_MPPE;
10108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
10128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->deflate_correct && len >= CILEN_DEFLATE
10138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& p[0] == CI_DEFLATE && p[1] == CILEN_DEFLATE) {
10148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
10158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    || p[3] != DEFLATE_CHK_SEQUENCE)
10168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 0;		/* Rej is bad */
10178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.deflate_correct = 0;
10188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p += CILEN_DEFLATE;
10198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_DEFLATE;
10208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->deflate_draft && len >= CILEN_DEFLATE
10228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& p[0] == CI_DEFLATE_DRAFT && p[1] == CILEN_DEFLATE) {
10238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
10248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    || p[3] != DEFLATE_CHK_SEQUENCE)
10258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 0;		/* Rej is bad */
10268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.deflate_draft = 0;
10278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p += CILEN_DEFLATE;
10288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_DEFLATE;
10298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!try.deflate_correct && !try.deflate_draft)
10318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.deflate = 0;
10328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->bsd_compress && len >= CILEN_BSD_COMPRESS
10338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) {
10348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits))
10358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 0;
10368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.bsd_compress = 0;
10378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p += CILEN_BSD_COMPRESS;
10388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_BSD_COMPRESS;
10398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->predictor_1 && len >= CILEN_PREDICTOR_1
10418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& p[0] == CI_PREDICTOR_1 && p[1] == CILEN_PREDICTOR_1) {
10428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.predictor_1 = 0;
10438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p += CILEN_PREDICTOR_1;
10448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_PREDICTOR_1;
10458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->predictor_2 && len >= CILEN_PREDICTOR_2
10478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& p[0] == CI_PREDICTOR_2 && p[1] == CILEN_PREDICTOR_2) {
10488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.predictor_2 = 0;
10498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p += CILEN_PREDICTOR_2;
10508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_PREDICTOR_2;
10518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (len != 0)
10548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
10558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->state != OPENED)
10578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	*go = try;
10588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
10608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
10618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
10638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp_reqci - processed a received configure-request.
10648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Returns CONFACK, CONFNAK or CONFREJ and the packet modified
10658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * appropriately.
10668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
10678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
10688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_reqci(f, p, lenp, dont_nak)
10698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
10708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
10718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int *lenp;
10728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int dont_nak;
10738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
10748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int ret, newret, res;
10758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p0, *retp;
10768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len, clen, type, nb;
10778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_options *ho = &ccp_hisoptions[f->unit];
10788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_options *ao = &ccp_allowoptions[f->unit];
10798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
10808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    bool rej_for_ci_mppe = 1;	/* Are we rejecting based on a bad/missing */
10818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				/* CI_MPPE, or due to other options?       */
10828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
10838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ret = CONFACK;
10858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    retp = p0 = p;
10868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    len = *lenp;
10878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(ho, 0, sizeof(ccp_options));
10898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ho->method = (len > 0)? p[0]: -1;
10908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while (len > 0) {
10928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	newret = CONFACK;
10938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len < 2 || p[1] < 2 || p[1] > len) {
10948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* length is bad */
10958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    clen = len;
10968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    newret = CONFREJ;
10978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else {
10998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    type = p[0];
11008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    clen = p[1];
11018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    switch (type) {
11038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
11048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_MPPE:
11058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (!ao->mppe || clen != CILEN_MPPE) {
11068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    newret = CONFREJ;
11078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
11088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
11098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		MPPE_CI_TO_OPTS(&p[2], ho->mppe);
11108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* Nak if anything unsupported or unknown are set. */
11128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (ho->mppe & MPPE_OPT_UNSUPPORTED) {
11138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    newret = CONFNAK;
11148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    ho->mppe &= ~MPPE_OPT_UNSUPPORTED;
11158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
11168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (ho->mppe & MPPE_OPT_UNKNOWN) {
11178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    newret = CONFNAK;
11188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    ho->mppe &= ~MPPE_OPT_UNKNOWN;
11198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
11208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* Check state opt */
11228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (ho->mppe & MPPE_OPT_STATEFUL) {
11238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    /*
11248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     * We can Nak and request stateless, but it's a
11258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     * lot easier to just assume the peer will request
11268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     * it if he can do it; stateful mode is bad over
11278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     * the Internet -- which is where we expect MPPE.
11288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     */
11298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   if (refuse_mppe_stateful) {
11308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			error("Refusing MPPE stateful mode offered by peer");
11318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			newret = CONFREJ;
11328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
11338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
11348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
11358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* Find out which of {S,L} are set. */
11378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if ((ho->mppe & MPPE_OPT_128)
11388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     && (ho->mppe & MPPE_OPT_40)) {
11398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    /* Both are set, negotiate the strongest. */
11408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    newret = CONFNAK;
11418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (ao->mppe & MPPE_OPT_128)
11428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			ho->mppe &= ~MPPE_OPT_40;
11438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    else if (ao->mppe & MPPE_OPT_40)
11448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			ho->mppe &= ~MPPE_OPT_128;
11458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    else {
11468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			newret = CONFREJ;
11478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
11488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
11498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} else if (ho->mppe & MPPE_OPT_128) {
11508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (!(ao->mppe & MPPE_OPT_128)) {
11518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			newret = CONFREJ;
11528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
11538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
11548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} else if (ho->mppe & MPPE_OPT_40) {
11558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (!(ao->mppe & MPPE_OPT_40)) {
11568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			newret = CONFREJ;
11578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
11588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
11598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} else {
11608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    /* Neither are set. */
11618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    newret = CONFREJ;
11628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
11638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
11648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* rebuild the opts */
11668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		MPPE_OPTS_TO_CI(ho->mppe, &p[2]);
11678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (newret == CONFACK) {
11688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN];
11698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    int mtu;
11708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    BCOPY(p, opt_buf, CILEN_MPPE);
11728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
11738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			  MPPE_MAX_KEY_LEN);
11748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (ccp_test(f->unit, opt_buf,
11758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 CILEN_MPPE + MPPE_MAX_KEY_LEN, 1) <= 0) {
11768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/* This shouldn't happen, we've already tested it! */
11778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			error("MPPE required, but kernel has no support.");
11788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			lcp_close(f->unit, "MPPE required but not available");
11798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			newret = CONFREJ;
11808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
11818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
11828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    /*
11838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     * We need to decrease the interface MTU by MPPE_PAD
11848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     * because MPPE frames **grow**.  The kernel [must]
11858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     * allocate MPPE_PAD extra bytes in xmit buffers.
11868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     */
11878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    mtu = netif_get_mtu(f->unit);
11888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (mtu)
11898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			netif_set_mtu(f->unit, mtu - MPPE_PAD);
11908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    else
11918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			newret = CONFREJ;
11928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
11938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/*
11958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * We have accepted MPPE or are willing to negotiate
11968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * MPPE parameters.  A CONFREJ is due to subsequent
11978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * (non-MPPE) processing.
11988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 */
11998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		rej_for_ci_mppe = 0;
12008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
12018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* MPPE */
12028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_DEFLATE:
12038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_DEFLATE_DRAFT:
12048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (!ao->deflate || clen != CILEN_DEFLATE
12058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    || (!ao->deflate_correct && type == CI_DEFLATE)
12068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    || (!ao->deflate_draft && type == CI_DEFLATE_DRAFT)) {
12078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    newret = CONFREJ;
12088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
12098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
12108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ho->deflate = 1;
12128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ho->deflate_size = nb = DEFLATE_SIZE(p[2]);
12138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL
12148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    || p[3] != DEFLATE_CHK_SEQUENCE
12158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    || nb > ao->deflate_size || nb < DEFLATE_MIN_WORKS) {
12168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    newret = CONFNAK;
12178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (!dont_nak) {
12188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			p[2] = DEFLATE_MAKE_OPT(ao->deflate_size);
12198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			p[3] = DEFLATE_CHK_SEQUENCE;
12208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/* fall through to test this #bits below */
12218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    } else
12228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
12238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
12248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/*
12268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * Check whether we can do Deflate with the window
12278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * size they want.  If the window is too big, reduce
12288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * it until the kernel can cope and nak with that.
12298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * We only check this for the first option.
12308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 */
12318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (p == p0) {
12328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    for (;;) {
12338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			res = ccp_test(f->unit, p, CILEN_DEFLATE, 1);
12348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (res > 0)
12358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    break;		/* it's OK now */
12368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (res < 0 || nb == DEFLATE_MIN_WORKS || dont_nak) {
12378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    newret = CONFREJ;
12388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    p[2] = DEFLATE_MAKE_OPT(ho->deflate_size);
12398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    break;
12408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
12418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			newret = CONFNAK;
12428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			--nb;
12438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			p[2] = DEFLATE_MAKE_OPT(nb);
12448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
12458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
12468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
12478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_BSD_COMPRESS:
12498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (!ao->bsd_compress || clen != CILEN_BSD_COMPRESS) {
12508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    newret = CONFREJ;
12518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
12528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
12538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ho->bsd_compress = 1;
12558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ho->bsd_bits = nb = BSD_NBITS(p[2]);
12568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION
12578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    || nb > ao->bsd_bits || nb < BSD_MIN_BITS) {
12588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    newret = CONFNAK;
12598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (!dont_nak) {
12608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, ao->bsd_bits);
12618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/* fall through to test this #bits below */
12628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    } else
12638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
12648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
12658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/*
12678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * Check whether we can do BSD-Compress with the code
12688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * size they want.  If the code size is too big, reduce
12698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * it until the kernel can cope and nak with that.
12708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * We only check this for the first option.
12718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 */
12728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (p == p0) {
12738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    for (;;) {
12748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 1);
12758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (res > 0)
12768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    break;
12778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (res < 0 || nb == BSD_MIN_BITS || dont_nak) {
12788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    newret = CONFREJ;
12798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION,
12808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project						ho->bsd_bits);
12818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    break;
12828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
12838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			newret = CONFNAK;
12848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			--nb;
12858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, nb);
12868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
12878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
12888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
12898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_PREDICTOR_1:
12918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (!ao->predictor_1 || clen != CILEN_PREDICTOR_1) {
12928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    newret = CONFREJ;
12938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
12948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
12958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ho->predictor_1 = 1;
12978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (p == p0
12988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    && ccp_test(f->unit, p, CILEN_PREDICTOR_1, 1) <= 0) {
12998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    newret = CONFREJ;
13008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
13018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
13028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_PREDICTOR_2:
13048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (!ao->predictor_2 || clen != CILEN_PREDICTOR_2) {
13058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    newret = CONFREJ;
13068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
13078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
13088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ho->predictor_2 = 1;
13108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (p == p0
13118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    && ccp_test(f->unit, p, CILEN_PREDICTOR_2, 1) <= 0) {
13128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    newret = CONFREJ;
13138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
13148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
13158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    default:
13178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		newret = CONFREJ;
13188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
13198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
13208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (newret == CONFNAK && dont_nak)
13228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    newret = CONFREJ;
13238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!(newret == CONFACK || (newret == CONFNAK && ret == CONFREJ))) {
13248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* we're returning this option */
13258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (newret == CONFREJ && ret == CONFNAK)
13268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		retp = p0;
13278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ret = newret;
13288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (p != retp)
13298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		BCOPY(p, retp, clen);
13308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    retp += clen;
13318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
13328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p += clen;
13348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= clen;
13358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ret != CONFACK) {
13388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ret == CONFREJ && *lenp == retp - p0)
13398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    all_rejected[f->unit] = 1;
13408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	else
13418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    *lenp = retp - p0;
13428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
13448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ret == CONFREJ && ao->mppe && rej_for_ci_mppe) {
13458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("MPPE required but peer negotiation failed");
13468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	lcp_close(f->unit, "MPPE required but peer negotiation failed");
13478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
13498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return ret;
13508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
13538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Make a string name for a compression method (or 2).
13548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
13558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char *
13568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectmethod_name(opt, opt2)
13578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_options *opt, *opt2;
13588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
13598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    static char result[64];
13608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!ANY_COMPRESS(*opt))
13628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return "(none)";
13638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    switch (opt->method) {
13648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
13658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CI_MPPE:
13668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    {
13678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	char *p = result;
13688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	char *q = result + sizeof(result); /* 1 past result */
13698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	slprintf(p, q - p, "MPPE ");
13718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p += 5;
13728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (opt->mppe & MPPE_OPT_128) {
13738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    slprintf(p, q - p, "128-bit ");
13748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p += 8;
13758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
13768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (opt->mppe & MPPE_OPT_40) {
13778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    slprintf(p, q - p, "40-bit ");
13788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p += 7;
13798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
13808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (opt->mppe & MPPE_OPT_STATEFUL)
13818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    slprintf(p, q - p, "stateful");
13828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	else
13838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    slprintf(p, q - p, "stateless");
13848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
13868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
13888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CI_DEFLATE:
13898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CI_DEFLATE_DRAFT:
13908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (opt2 != NULL && opt2->deflate_size != opt->deflate_size)
13918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    slprintf(result, sizeof(result), "Deflate%s (%d/%d)",
13928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""),
13938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     opt->deflate_size, opt2->deflate_size);
13948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	else
13958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    slprintf(result, sizeof(result), "Deflate%s (%d)",
13968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""),
13978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     opt->deflate_size);
13988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
13998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CI_BSD_COMPRESS:
14008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits)
14018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    slprintf(result, sizeof(result), "BSD-Compress (%d/%d)",
14028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     opt->bsd_bits, opt2->bsd_bits);
14038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	else
14048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    slprintf(result, sizeof(result), "BSD-Compress (%d)",
14058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     opt->bsd_bits);
14068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
14078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CI_PREDICTOR_1:
14088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return "Predictor 1";
14098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CI_PREDICTOR_2:
14108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return "Predictor 2";
14118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    default:
14128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	slprintf(result, sizeof(result), "Method %d", opt->method);
14138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
14148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return result;
14158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
14168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
14188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * CCP has come up - inform the kernel driver and log a message.
14198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
14208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
14218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_up(f)
14228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
14238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
14248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_options *go = &ccp_gotoptions[f->unit];
14258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_options *ho = &ccp_hisoptions[f->unit];
14268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char method1[64];
14278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_flags_set(f->unit, 1, 1);
14298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ANY_COMPRESS(*go)) {
14308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ANY_COMPRESS(*ho)) {
14318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->method == ho->method) {
14328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		notice("%s compression enabled", method_name(go, ho));
14338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    } else {
14348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		strlcpy(method1, method_name(go, NULL), sizeof(method1));
14358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		notice("%s / %s compression enabled",
14368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		       method1, method_name(ho, NULL));
14378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
14388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else
14398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    notice("%s receive compression enabled", method_name(go, NULL));
14408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else if (ANY_COMPRESS(*ho))
14418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	notice("%s transmit compression enabled", method_name(ho, NULL));
14428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
14438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->mppe) {
14448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	BZERO(mppe_recv_key, MPPE_MAX_KEY_LEN);
14458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	BZERO(mppe_send_key, MPPE_MAX_KEY_LEN);
14468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	continue_networks(f->unit);		/* Bring up IP et al */
14478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
14488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
14498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
14508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
14528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * CCP has gone down - inform the kernel driver.
14538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
14548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
14558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_down(f)
14568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
14578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
14588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ccp_localstate[f->unit] & RACK_PENDING)
14598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	UNTIMEOUT(ccp_rack_timeout, f);
14608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_localstate[f->unit] = 0;
14618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ccp_flags_set(f->unit, 1, 0);
14628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
14638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ccp_gotoptions[f->unit].mppe) {
14648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ccp_gotoptions[f->unit].mppe = 0;
14658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (lcp_fsm[f->unit].state == OPENED) {
14668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* If LCP is not already going down, make sure it does. */
14678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("MPPE disabled");
14688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    lcp_close(f->unit, "MPPE disabled");
14698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
14708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
14718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
14728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
14738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
14758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Print the contents of a CCP packet.
14768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
14778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char *ccp_codenames[] = {
14788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    "ConfReq", "ConfAck", "ConfNak", "ConfRej",
14798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    "TermReq", "TermAck", "CodeRej",
14808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL, NULL, NULL, NULL, NULL, NULL,
14818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    "ResetReq", "ResetAck",
14828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
14838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
14858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_printpkt(p, plen, printer, arg)
14868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
14878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int plen;
14888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    void (*printer) __P((void *, char *, ...));
14898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    void *arg;
14908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
14918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p0, *optend;
14928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int code, id, len;
14938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int optlen;
14948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    p0 = p;
14968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (plen < HEADERLEN)
14978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
14988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    code = p[0];
14998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    id = p[1];
15008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    len = (p[2] << 8) + p[3];
15018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (len < HEADERLEN || len > plen)
15028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
15038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (code >= 1 && code <= sizeof(ccp_codenames) / sizeof(char *)
15058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& ccp_codenames[code-1] != NULL)
15068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	printer(arg, " %s", ccp_codenames[code-1]);
15078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    else
15088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	printer(arg, " code=0x%x", code);
15098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    printer(arg, " id=0x%x", id);
15108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    len -= HEADERLEN;
15118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    p += HEADERLEN;
15128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    switch (code) {
15148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFREQ:
15158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFACK:
15168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFNAK:
15178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFREJ:
15188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* print list of possible compression methods */
15198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	while (len >= 2) {
15208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    code = p[0];
15218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    optlen = p[1];
15228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (optlen < 2 || optlen > len)
15238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    printer(arg, " <");
15258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    len -= optlen;
15268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    optend = p + optlen;
15278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    switch (code) {
15288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
15298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_MPPE:
15308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (optlen >= CILEN_MPPE) {
15318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    u_char mppe_opts;
15328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    MPPE_CI_TO_OPTS(&p[2], mppe_opts);
15348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "mppe %s %s %s %s %s %s%s",
15358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    (p[2] & MPPE_H_BIT)? "+H": "-H",
15368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    (p[5] & MPPE_M_BIT)? "+M": "-M",
15378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    (p[5] & MPPE_S_BIT)? "+S": "-S",
15388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    (p[5] & MPPE_L_BIT)? "+L": "-L",
15398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    (p[5] & MPPE_D_BIT)? "+D": "-D",
15408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    (p[5] & MPPE_C_BIT)? "+C": "-C",
15418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    (mppe_opts & MPPE_OPT_UNKNOWN)? " +U": "");
15428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (mppe_opts & MPPE_OPT_UNKNOWN)
15438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, " (%.2x %.2x %.2x %.2x)",
15448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				p[2], p[3], p[4], p[5]);
15458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += CILEN_MPPE;
15468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
15478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
15498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_DEFLATE:
15508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_DEFLATE_DRAFT:
15518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (optlen >= CILEN_DEFLATE) {
15528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "deflate%s %d",
15538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    (code == CI_DEFLATE_DRAFT? "(old#)": ""),
15548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    DEFLATE_SIZE(p[2]));
15558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL)
15568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, " method %d", DEFLATE_METHOD(p[2]));
15578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (p[3] != DEFLATE_CHK_SEQUENCE)
15588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, " check %d", p[3]);
15598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += CILEN_DEFLATE;
15608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
15618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_BSD_COMPRESS:
15638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (optlen >= CILEN_BSD_COMPRESS) {
15648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "bsd v%d %d", BSD_VERSION(p[2]),
15658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    BSD_NBITS(p[2]));
15668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += CILEN_BSD_COMPRESS;
15678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
15688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_PREDICTOR_1:
15708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (optlen >= CILEN_PREDICTOR_1) {
15718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "predictor 1");
15728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += CILEN_PREDICTOR_1;
15738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
15748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_PREDICTOR_2:
15768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (optlen >= CILEN_PREDICTOR_2) {
15778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "predictor 2");
15788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += CILEN_PREDICTOR_2;
15798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
15808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
15828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    while (p < optend)
15838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		printer(arg, " %.2x", *p++);
15848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    printer(arg, ">");
15858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
15868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
15878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case TERMACK:
15898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case TERMREQ:
15908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len > 0 && *p >= ' ' && *p < 0x7f) {
15918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    print_string((char *)p, len, printer, arg);
15928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p += len;
15938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    len = 0;
15948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
15958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
15968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
15978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* dump out the rest of the packet in hex */
15998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while (--len >= 0)
16008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	printer(arg, " %.2x", *p++);
16018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return p - p0;
16038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
16048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
16068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * We have received a packet that the decompressor failed to
16078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * decompress.  Here we would expect to issue a reset-request, but
16088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Motorola has a patent on resetting the compressor as a result of
16098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * detecting an error in the decompressed data after decompression.
16108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * (See US patent 5,130,993; international patent publication number
16118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * WO 91/10289; Australian patent 73296/91.)
16128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
16138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * So we ask the kernel whether the error was detected after
16148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * decompression; if it was, we take CCP down, thus disabling
16158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * compression :-(, otherwise we issue the reset-request.
16168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
16178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
16188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_datainput(unit, pkt, len)
16198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
16208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *pkt;
16218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
16228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
16238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
16248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    f = &ccp_fsm[unit];
16268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->state == OPENED) {
16278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ccp_fatal_error(unit)) {
16288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
16298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * Disable compression by taking CCP down.
16308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
16318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Lost compression sync: disabling compression");
16328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ccp_close(unit, "Lost compression sync");
16338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
16348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
16358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * If we were doing MPPE, we must also take the link down.
16368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
16378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (ccp_gotoptions[unit].mppe) {
16388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		error("Too many MPPE errors, closing LCP");
16398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		lcp_close(unit, "Too many MPPE errors");
16408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
16418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
16428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else {
16438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
16448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * Send a reset-request to reset the peer's compressor.
16458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * We don't do that if we are still waiting for an
16468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * acknowledgement to a previous reset-request.
16478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
16488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!(ccp_localstate[f->unit] & RACK_PENDING)) {
16498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0);
16508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT);
16518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ccp_localstate[f->unit] |= RACK_PENDING;
16528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    } else
16538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ccp_localstate[f->unit] |= RREQ_REPEAT;
16548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
16558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
16568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
16578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
16598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Timeout waiting for reset-ack.
16608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
16618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
16628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_rack_timeout(arg)
16638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    void *arg;
16648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
16658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f = arg;
16668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->state == OPENED && ccp_localstate[f->unit] & RREQ_REPEAT) {
16688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fsm_sdata(f, CCP_RESETREQ, f->reqid, NULL, 0);
16698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT);
16708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ccp_localstate[f->unit] &= ~RREQ_REPEAT;
16718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else
16728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ccp_localstate[f->unit] &= ~RACK_PENDING;
16738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
16748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1675