18ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
28ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp.c - PPP Link Control Protocol.
38ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
48ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Copyright (c) 1984-2000 Carnegie Mellon University. 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. Redistributions in binary form must reproduce the above copyright
148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    notice, this list of conditions and the following disclaimer in
158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    the documentation and/or other materials provided with the
168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    distribution.
178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 3. The name "Carnegie Mellon University" must not be used to
198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    endorse or promote products derived from this software without
208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    prior written permission. For permission or any legal
218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    details, please contact
228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *      Office of Technology Transfer
238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *      Carnegie Mellon University
248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *      5000 Forbes Avenue
258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *      Pittsburgh, PA  15213-3890
268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *      (412) 268-4387, fax: (412) 268-7395
278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *      tech-transfer@andrew.cmu.edu
288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 4. Redistributions of any form whatsoever must retain the following
308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    acknowledgment:
318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    "This product includes software developed by Computing Services
328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
431286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley#define RCSID	"$Id: lcp.c,v 1.76 2006/05/22 00:04:07 paulus Exp $"
448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * TODO:
478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdio.h>
508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <string.h>
518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdlib.h>
528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "pppd.h"
548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "fsm.h"
558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "lcp.h"
568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "chap-new.h"
578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "magic.h"
588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic const char rcsid[] = RCSID;
608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * When the link comes up we want to be able to wait for a short while,
638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * or until seeing some input from the peer, before starting to send
648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * configure-requests.  We do this by delaying the fsm_lowerup call.
658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* steal a bit in fsm flags word */
678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define DELAYED_UP	0x100
688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void lcp_delayed_up __P((void *));
708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * LCP-related command-line options.
738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint	lcp_echo_interval = 0; 	/* Interval between LCP echo-requests */
758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint	lcp_echo_fails = 0;	/* Tolerance to unanswered echo-requests */
768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectbool	lax_recv = 0;		/* accept control chars in asyncmap */
778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectbool	noendpoint = 0;		/* don't send/accept endpoint discriminator */
788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int noopt __P((char **));
808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef HAVE_MULTILINK
828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int setendpoint __P((char **));
838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void printendpoint __P((option_t *, void (*)(void *, char *, ...),
848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			       void *));
858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* HAVE_MULTILINK */
868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic option_t lcp_option_list[] = {
888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* LCP options */
898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "-all", o_special_noarg, (void *)noopt,
908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Don't request/allow any LCP options" },
918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "noaccomp", o_bool, &lcp_wantoptions[0].neg_accompression,
938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Disable address/control compression",
948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_A2CLR, &lcp_allowoptions[0].neg_accompression },
958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "-ac", o_bool, &lcp_wantoptions[0].neg_accompression,
968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Disable address/control compression",
978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_accompression },
988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap,
1008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set asyncmap (for received packets)",
1018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_OR, &lcp_wantoptions[0].neg_asyncmap },
1028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "-as", o_uint32, &lcp_wantoptions[0].asyncmap,
1038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set asyncmap (for received packets)",
1048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_ALIAS | OPT_OR, &lcp_wantoptions[0].neg_asyncmap },
1058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "default-asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap,
1068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Disable asyncmap negotiation",
1078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR,
1088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      &lcp_allowoptions[0].neg_asyncmap },
1098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "-am", o_uint32, &lcp_wantoptions[0].asyncmap,
1108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Disable asyncmap negotiation",
1118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_ALIAS | OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR,
1128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      &lcp_allowoptions[0].neg_asyncmap },
1138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "nomagic", o_bool, &lcp_wantoptions[0].neg_magicnumber,
1158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Disable magic number negotiation (looped-back line detection)",
1168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber },
1178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "-mn", o_bool, &lcp_wantoptions[0].neg_magicnumber,
1188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Disable magic number negotiation (looped-back line detection)",
1198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber },
1208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "mru", o_int, &lcp_wantoptions[0].mru,
1228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set MRU (maximum received packet size) for negotiation",
1238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_PRIO, &lcp_wantoptions[0].neg_mru },
1248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "default-mru", o_bool, &lcp_wantoptions[0].neg_mru,
1258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Disable MRU negotiation (use default 1500)",
1268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru },
1278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "-mru", o_bool, &lcp_wantoptions[0].neg_mru,
1288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Disable MRU negotiation (use default 1500)",
1298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru },
1308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "mtu", o_int, &lcp_allowoptions[0].mru,
1328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set our MTU", OPT_LIMITS, NULL, MAXMRU, MINMRU },
1338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "nopcomp", o_bool, &lcp_wantoptions[0].neg_pcompression,
1358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Disable protocol field compression",
1368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression },
1378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "-pc", o_bool, &lcp_wantoptions[0].neg_pcompression,
1388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Disable protocol field compression",
1398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression },
1408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "passive", o_bool, &lcp_wantoptions[0].passive,
1428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set passive mode", 1 },
1438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "-p", o_bool, &lcp_wantoptions[0].passive,
1448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set passive mode", OPT_ALIAS | 1 },
1458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "silent", o_bool, &lcp_wantoptions[0].silent,
1478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set silent mode", 1 },
1488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "lcp-echo-failure", o_int, &lcp_echo_fails,
1508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set number of consecutive echo failures to indicate link failure",
1518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_PRIO },
1528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "lcp-echo-interval", o_int, &lcp_echo_interval,
1538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set time in seconds between LCP echo requests", OPT_PRIO },
1548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "lcp-restart", o_int, &lcp_fsm[0].timeouttime,
1558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set time in seconds between LCP retransmissions", OPT_PRIO },
1568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits,
1578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set maximum number of LCP terminate-request transmissions", OPT_PRIO },
1588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "lcp-max-configure", o_int, &lcp_fsm[0].maxconfreqtransmits,
1598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set maximum number of LCP configure-request transmissions", OPT_PRIO },
1608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "lcp-max-failure", o_int, &lcp_fsm[0].maxnakloops,
1618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set limit on number of LCP configure-naks", OPT_PRIO },
1628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "receive-all", o_bool, &lax_recv,
1648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Accept all received control characters", 1 },
1658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef HAVE_MULTILINK
1678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "mrru", o_int, &lcp_wantoptions[0].mrru,
1688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Maximum received packet size for multilink bundle",
1698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_PRIO, &lcp_wantoptions[0].neg_mrru },
1708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "mpshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf,
1728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Use short sequence numbers in multilink headers",
1738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_PRIO | 1, &lcp_allowoptions[0].neg_ssnhf },
1748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "nompshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf,
1758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Don't use short sequence numbers in multilink headers",
1768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_ssnhf },
1778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "endpoint", o_special, (void *) setendpoint,
1798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Endpoint discriminator for multilink",
1808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      OPT_PRIO | OPT_A2PRINTER, (void *) printendpoint },
1818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* HAVE_MULTILINK */
1828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "noendpoint", o_bool, &noendpoint,
1848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Don't send or accept multilink endpoint discriminator", 1 },
1858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    {NULL}
1878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
1888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* global vars */
1908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectfsm lcp_fsm[NUM_PPP];			/* LCP fsm structure (global)*/
1918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_options lcp_wantoptions[NUM_PPP];	/* Options that we want to request */
1928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_options lcp_gotoptions[NUM_PPP];	/* Options that peer ack'd */
1938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_options lcp_allowoptions[NUM_PPP];	/* Options we allow peer to request */
1948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_options lcp_hisoptions[NUM_PPP];	/* Options that we ack'd */
1958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int lcp_echos_pending = 0;	/* Number of outstanding echo msgs */
1978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int lcp_echo_number   = 0;	/* ID number of next echo frame */
1988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int lcp_echo_timer_running = 0;  /* set if a timer is running */
1998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic u_char nak_buffer[PPP_MRU];	/* where we construct a nak packet */
2018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Callbacks for fsm code.  (CI = Configuration Information)
2048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
2058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void lcp_resetci __P((fsm *));	/* Reset our CI */
2068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  lcp_cilen __P((fsm *));		/* Return length of our CI */
2078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void lcp_addci __P((fsm *, u_char *, int *)); /* Add our CI to pkt */
2088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  lcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */
2098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  lcp_nakci __P((fsm *, u_char *, int, int)); /* Peer nak'd our CI */
2108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  lcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */
2118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  lcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv peer CI */
2128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void lcp_up __P((fsm *));		/* We're UP */
2138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void lcp_down __P((fsm *));		/* We're DOWN */
2148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void lcp_starting __P((fsm *));	/* We need lower layer up */
2158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void lcp_finished __P((fsm *));	/* We need lower layer down */
2168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  lcp_extcode __P((fsm *, int, int, u_char *, int));
2178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void lcp_rprotrej __P((fsm *, u_char *, int));
2188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * routines to send LCP echos to peer
2218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
2228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void lcp_echo_lowerup __P((int));
2248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void lcp_echo_lowerdown __P((int));
2258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void LcpEchoTimeout __P((void *));
2268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void lcp_received_echo_reply __P((fsm *, int, u_char *, int));
2278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void LcpSendEchoRequest __P((fsm *));
2288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void LcpLinkFailure __P((fsm *));
2298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void LcpEchoCheck __P((fsm *));
2308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic fsm_callbacks lcp_callbacks = {	/* LCP callback routines */
2328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_resetci,		/* Reset our Configuration Information */
2338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_cilen,			/* Length of our Configuration Information */
2348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_addci,			/* Add our Configuration Information */
2358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_ackci,			/* ACK our Configuration Information */
2368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_nakci,			/* NAK our Configuration Information */
2378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_rejci,			/* Reject our Configuration Information */
2388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_reqci,			/* Request peer's Configuration Information */
2398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_up,			/* Called when fsm reaches OPENED state */
2408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_down,			/* Called when fsm leaves OPENED state */
2418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_starting,		/* Called when we want the lower layer up */
2428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_finished,		/* Called when we want the lower layer down */
2438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL,			/* Called when Protocol-Reject received */
2448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL,			/* Retransmission is necessary */
2458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_extcode,		/* Called to handle LCP-specific codes */
2468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    "LCP"			/* String name of protocol */
2478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
2488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Protocol entry points.
2518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Some of these are called directly.
2528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
2538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void lcp_init __P((int));
2558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void lcp_input __P((int, u_char *, int));
2568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void lcp_protrej __P((int));
2578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  lcp_printpkt __P((u_char *, int,
2588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			      void (*) __P((void *, char *, ...)), void *));
2598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstruct protent lcp_protent = {
2618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    PPP_LCP,
2628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_init,
2638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_input,
2648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_protrej,
2658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_lowerup,
2668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_lowerdown,
2678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_open,
2688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_close,
2698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_printpkt,
2708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL,
2718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    1,
2728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    "LCP",
2738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL,
2748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_option_list,
2758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL,
2768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL,
2778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL
2788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
2798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint lcp_loopbackfail = DEFLOOPBACKFAIL;
2818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Length of each type of configuration option (in octets)
2848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
2858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define CILEN_VOID	2
2868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define CILEN_CHAR	3
2878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define CILEN_SHORT	4	/* CILEN_VOID + 2 */
2888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define CILEN_CHAP	5	/* CILEN_VOID + 2 + 1 */
2898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define CILEN_LONG	6	/* CILEN_VOID + 4 */
2908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define CILEN_LQR	8	/* CILEN_VOID + 2 + 4 */
2918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define CILEN_CBCP	3
2928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define CODENAME(x)	((x) == CONFACK ? "ACK" : \
2948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			 (x) == CONFNAK ? "NAK" : "REJ")
2958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * noopt - Disable all options (why?).
2988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
2998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
3008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectnoopt(argv)
3018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char **argv;
3028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
3038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options));
3048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options));
3058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return (1);
3078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
3088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef HAVE_MULTILINK
3108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
3118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsetendpoint(argv)
3128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char **argv;
3138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
3148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (str_to_epdisc(&lcp_wantoptions[0].endpoint, *argv)) {
3158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	lcp_wantoptions[0].neg_endpoint = 1;
3168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 1;
3178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    option_error("Can't parse '%s' as an endpoint discriminator", *argv);
3198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
3208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
3218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
3238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectprintendpoint(opt, printer, arg)
3248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    option_t *opt;
3258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    void (*printer) __P((void *, char *, ...));
3268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    void *arg;
3278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
3288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	printer(arg, "%s", epdisc_to_str(&lcp_wantoptions[0].endpoint));
3298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
3308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* HAVE_MULTILINK */
3318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
3338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_init - Initialize LCP.
3348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
3358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
3368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_init(unit)
3378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
3388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
3398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f = &lcp_fsm[unit];
3408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *wo = &lcp_wantoptions[unit];
3418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *ao = &lcp_allowoptions[unit];
3428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    f->unit = unit;
3448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    f->protocol = PPP_LCP;
3458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    f->callbacks = &lcp_callbacks;
3468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_init(f);
3488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    BZERO(wo, sizeof(*wo));
3508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    wo->neg_mru = 1;
3518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    wo->mru = DEFMRU;
3528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    wo->neg_asyncmap = 1;
3538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    wo->neg_magicnumber = 1;
3548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    wo->neg_pcompression = 1;
3558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    wo->neg_accompression = 1;
3568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    BZERO(ao, sizeof(*ao));
3588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ao->neg_mru = 1;
3598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ao->mru = MAXMRU;
3608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ao->neg_asyncmap = 1;
3618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ao->neg_chap = 1;
3628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ao->chap_mdtype = chap_mdtype_all;
3638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ao->neg_upap = 1;
3648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ao->neg_eap = 1;
3658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ao->neg_magicnumber = 1;
3668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ao->neg_pcompression = 1;
3678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ao->neg_accompression = 1;
3688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ao->neg_endpoint = 1;
3698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
3708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
3738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_open - LCP is allowed to come up.
3748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
3758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
3768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_open(unit)
3778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
3788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
3798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f = &lcp_fsm[unit];
3808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *wo = &lcp_wantoptions[unit];
3818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    f->flags &= ~(OPT_PASSIVE | OPT_SILENT);
3838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (wo->passive)
3848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	f->flags |= OPT_PASSIVE;
3858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (wo->silent)
3868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	f->flags |= OPT_SILENT;
3878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_open(f);
3888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
3898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
3928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_close - Take LCP down.
3938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
3948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
3958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_close(unit, reason)
3968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
3978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *reason;
3988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
3998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f = &lcp_fsm[unit];
4001286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    int oldstate;
4018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (phase != PHASE_DEAD && phase != PHASE_MASTER)
4038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	new_phase(PHASE_TERMINATE);
4041286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley
4051286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    if (f->flags & DELAYED_UP) {
4061286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	untimeout(lcp_delayed_up, f);
4071286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	f->state = STOPPED;
4081286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    }
4091286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    oldstate = f->state;
4101286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley
4111286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    fsm_close(f, reason);
4121286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    if (oldstate == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT|DELAYED_UP)) {
4138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
4148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * This action is not strictly according to the FSM in RFC1548,
4158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * but it does mean that the program terminates if you do a
4161286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	 * lcp_close() when a connection hasn't been established
4171286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	 * because we are in passive/silent mode or because we have
4181286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	 * delayed the fsm_lowerup() call and it hasn't happened yet.
4198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
4201286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	f->flags &= ~DELAYED_UP;
4218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	lcp_finished(f);
4221286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    }
4238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_lowerup - The lower layer is up.
4288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
4308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_lowerup(unit)
4318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
4328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *wo = &lcp_wantoptions[unit];
4348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f = &lcp_fsm[unit];
4358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
4378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Don't use A/C or protocol compression on transmission,
4388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * but accept A/C and protocol compressed packets
4398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * if we are going to ask for A/C and protocol compression.
4408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
4418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0) < 0
4428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	|| ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff),
4438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			   wo->neg_pcompression, wo->neg_accompression) < 0)
4448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return;
4458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    peer_mru[unit] = PPP_MRU;
4468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (listen_time != 0) {
4488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	f->flags |= DELAYED_UP;
4498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	timeout(lcp_delayed_up, f, 0, listen_time * 1000);
4508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else
4518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fsm_lowerup(f);
4528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_lowerdown - The lower layer is down.
4578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
4598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_lowerdown(unit)
4608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
4618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f = &lcp_fsm[unit];
4638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4641286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    if (f->flags & DELAYED_UP) {
4658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	f->flags &= ~DELAYED_UP;
4661286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	untimeout(lcp_delayed_up, f);
4671286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    } else
4688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fsm_lowerdown(&lcp_fsm[unit]);
4698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_delayed_up - Bring the lower layer up now.
4748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
4768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_delayed_up(arg)
4778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    void *arg;
4788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f = arg;
4808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->flags & DELAYED_UP) {
4828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	f->flags &= ~DELAYED_UP;
4838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fsm_lowerup(f);
4848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
4858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_input - Input LCP packet.
4908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
4928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_input(unit, p, len)
4938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
4948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
4958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
4968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f = &lcp_fsm[unit];
4988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->flags & DELAYED_UP) {
5008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	f->flags &= ~DELAYED_UP;
5011286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	untimeout(lcp_delayed_up, f);
5028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fsm_lowerup(f);
5038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
5048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_input(f, p, len);
5058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
5068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
5088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_extcode - Handle a LCP-specific code.
5098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
5108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
5118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_extcode(f, code, id, inp, len)
5128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
5138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int code, id;
5148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *inp;
5158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
5168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
5178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *magp;
5188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    switch( code ){
5208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case PROTREJ:
5218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	lcp_rprotrej(f, inp, len);
5228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
5238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case ECHOREQ:
5258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (f->state != OPENED)
5268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
5278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	magp = inp;
5288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);
5298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fsm_sdata(f, ECHOREP, id, inp, len);
5308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
5318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case ECHOREP:
5338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	lcp_received_echo_reply(f, id, inp, len);
5348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
5358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case DISCREQ:
5371286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    case IDENTIF:
5381286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    case TIMEREM:
5398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
5408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    default:
5428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
5438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
5448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
5458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
5468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
5498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_rprotrej - Receive an Protocol-Reject.
5508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
5518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Figure out which protocol is rejected and inform it.
5528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
5538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
5548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_rprotrej(f, inp, len)
5558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
5568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *inp;
5578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
5588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
5598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int i;
5608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct protent *protp;
5618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_short prot;
5621286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    const char *pname;
5638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (len < 2) {
5658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	LCPDEBUG(("lcp_rprotrej: Rcvd short Protocol-Reject packet!"));
5668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
5678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
5688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    GETSHORT(prot, inp);
5708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
5728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Protocol-Reject packets received in any state other than the LCP
5738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * OPENED state SHOULD be silently discarded.
5748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
5758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if( f->state != OPENED ){
5768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	LCPDEBUG(("Protocol-Reject discarded: LCP in state %d", f->state));
5778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
5788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
5798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5801286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    pname = protocol_name(prot);
5811286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley
5828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
5838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Upcall the proper Protocol-Reject routine.
5848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
5858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (i = 0; (protp = protocols[i]) != NULL; ++i)
5868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (protp->protocol == prot && protp->enabled_flag) {
5871286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	    if (pname == NULL)
5881286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		dbglog("Protocol-Reject for 0x%x received", prot);
5891286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	    else
5901286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		dbglog("Protocol-Reject for '%s' (0x%x) received", pname,
5911286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		       prot);
5928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    (*protp->protrej)(f->unit);
5938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return;
5948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
5958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5961286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    if (pname == NULL)
5971286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	warn("Protocol-Reject for unsupported protocol 0x%x", prot);
5981286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    else
5991286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	warn("Protocol-Reject for unsupported protocol '%s' (0x%x)", pname,
6001286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	     prot);
6018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
6028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
6058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_protrej - A Protocol-Reject was received.
6068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
6078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*ARGSUSED*/
6088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
6098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_protrej(unit)
6108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
6118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
6128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
6138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Can't reject LCP!
6148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
6158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    error("Received Protocol-Reject for LCP!");
6168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_protreject(&lcp_fsm[unit]);
6178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
6188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
6218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_sprotrej - Send a Protocol-Reject for some protocol.
6228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
6238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
6248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_sprotrej(unit, p, len)
6258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
6268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
6278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
6288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
6298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
6308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Send back the protocol and the information field of the
6318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * rejected packet.  We only get here if LCP is in the OPENED state.
6328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
6338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    p += 2;
6348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    len -= 2;
6358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id,
6378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      p, len);
6388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
6398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
6428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_resetci - Reset our CI.
6438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
6448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
6458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_resetci(f)
6468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
6478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
6488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *wo = &lcp_wantoptions[f->unit];
6498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *go = &lcp_gotoptions[f->unit];
6508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *ao = &lcp_allowoptions[f->unit];
6518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    wo->magicnumber = magic();
6538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    wo->numloops = 0;
6548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    *go = *wo;
6558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!multilink) {
6568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	go->neg_mrru = 0;
6578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	go->neg_ssnhf = 0;
6588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	go->neg_endpoint = 0;
6598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (noendpoint)
6618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ao->neg_endpoint = 0;
6628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    peer_mru[f->unit] = PPP_MRU;
6638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    auth_reset(f->unit);
6648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
6658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
6688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_cilen - Return length of our CI.
6698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
6708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
6718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_cilen(f)
6728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
6738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
6748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *go = &lcp_gotoptions[f->unit];
6758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define LENCIVOID(neg)	((neg) ? CILEN_VOID : 0)
6778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define LENCICHAP(neg)	((neg) ? CILEN_CHAP : 0)
6788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define LENCISHORT(neg)	((neg) ? CILEN_SHORT : 0)
6798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define LENCILONG(neg)	((neg) ? CILEN_LONG : 0)
6808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define LENCILQR(neg)	((neg) ? CILEN_LQR: 0)
6818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define LENCICBCP(neg)	((neg) ? CILEN_CBCP: 0)
6828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
6838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * NB: we only ask for one of CHAP, UPAP, or EAP, even if we will
6848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * accept more than one.  We prefer EAP first, then CHAP, then
6858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * PAP.
6868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
6878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return (LENCISHORT(go->neg_mru && go->mru != DEFMRU) +
6888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) +
6898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCISHORT(go->neg_eap) +
6908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCICHAP(!go->neg_eap && go->neg_chap) +
6918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCISHORT(!go->neg_eap && !go->neg_chap && go->neg_upap) +
6928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCILQR(go->neg_lqr) +
6938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCICBCP(go->neg_cbcp) +
6948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCILONG(go->neg_magicnumber) +
6958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCIVOID(go->neg_pcompression) +
6968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCIVOID(go->neg_accompression) +
6978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCISHORT(go->neg_mrru) +
6988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCIVOID(go->neg_ssnhf) +
6998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    (go->neg_endpoint? CILEN_CHAR + go->endpoint.length: 0));
7008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
7018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
7048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_addci - Add our desired CIs to a packet.
7058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
7068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
7078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_addci(f, ucp, lenp)
7088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
7098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *ucp;
7108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int *lenp;
7118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
7128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *go = &lcp_gotoptions[f->unit];
7138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *start_ucp = ucp;
7148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ADDCIVOID(opt, neg) \
7168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
7178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(opt, ucp); \
7188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(CILEN_VOID, ucp); \
7198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ADDCISHORT(opt, neg, val) \
7218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
7228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(opt, ucp); \
7238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(CILEN_SHORT, ucp); \
7248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTSHORT(val, ucp); \
7258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ADDCICHAP(opt, neg, val) \
7278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
7288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR((opt), ucp); \
7298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(CILEN_CHAP, ucp); \
7308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTSHORT(PPP_CHAP, ucp); \
7318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR((CHAP_DIGEST(val)), ucp); \
7328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ADDCILONG(opt, neg, val) \
7348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
7358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(opt, ucp); \
7368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(CILEN_LONG, ucp); \
7378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTLONG(val, ucp); \
7388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ADDCILQR(opt, neg, val) \
7408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
7418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(opt, ucp); \
7428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(CILEN_LQR, ucp); \
7438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTSHORT(PPP_LQR, ucp); \
7448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTLONG(val, ucp); \
7458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ADDCICHAR(opt, neg, val) \
7478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
7488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(opt, ucp); \
7498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(CILEN_CHAR, ucp); \
7508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(val, ucp); \
7518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ADDCIENDP(opt, neg, class, val, len) \
7538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
7548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int i; \
7558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(opt, ucp); \
7568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(CILEN_CHAR + len, ucp); \
7578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(class, ucp); \
7588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	for (i = 0; i < len; ++i) \
7598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    PUTCHAR(val[i], ucp); \
7608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru);
7638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
7648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      go->asyncmap);
7658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP);
7668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype);
7678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap,
7688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	       PPP_PAP);
7698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
7708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
7718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
7728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
7738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
7748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCISHORT(CI_MRRU, go->neg_mrru, go->mrru);
7758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCIVOID(CI_SSNHF, go->neg_ssnhf);
7768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class,
7778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      go->endpoint.value, go->endpoint.length);
7788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ucp - start_ucp != *lenp) {
7808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* this should never happen, because peer_mtu should be 1500 */
7818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Bug in lcp_addci: wrong length");
7828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
7848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
7878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_ackci - Ack our CIs.
7888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This should not modify any state if the Ack is bad.
7898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
7908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Returns:
7918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *	0 - Ack was bad.
7928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *	1 - Ack was good.
7938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
7948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
7958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_ackci(f, p, len)
7968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
7978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
7988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
7998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
8008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *go = &lcp_gotoptions[f->unit];
8018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char cilen, citype, cichar;
8028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_short cishort;
8038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t cilong;
8048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
8068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * CIs must be in exactly the same order that we sent.
8078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Check packet length and CI length at each step.
8088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If we find any deviations, then this packet is bad.
8098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
8108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCIVOID(opt, neg) \
8118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
8128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((len -= CILEN_VOID) < 0) \
8138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
8158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
8168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != CILEN_VOID || \
8178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype != opt) \
8188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCISHORT(opt, neg, val) \
8218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
8228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((len -= CILEN_SHORT) < 0) \
8238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
8258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
8268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != CILEN_SHORT || \
8278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype != opt) \
8288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p); \
8308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cishort != val) \
8318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCICHAR(opt, neg, val) \
8348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
8358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((len -= CILEN_CHAR) < 0) \
8368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
8388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
8398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != CILEN_CHAR || \
8408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype != opt) \
8418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cichar, p); \
8438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cichar != val) \
8448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCICHAP(opt, neg, val) \
8478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
8488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((len -= CILEN_CHAP) < 0) \
8498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
8518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
8528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != CILEN_CHAP || \
8538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype != (opt)) \
8548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p); \
8568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cishort != PPP_CHAP) \
8578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cichar, p); \
8598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cichar != (CHAP_DIGEST(val))) \
8608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	  goto bad; \
8618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCILONG(opt, neg, val) \
8638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
8648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((len -= CILEN_LONG) < 0) \
8658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
8678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
8688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != CILEN_LONG || \
8698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype != opt) \
8708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETLONG(cilong, p); \
8728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilong != val) \
8738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCILQR(opt, neg, val) \
8768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
8778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((len -= CILEN_LQR) < 0) \
8788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
8808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
8818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != CILEN_LQR || \
8828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype != opt) \
8838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p); \
8858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cishort != PPP_LQR) \
8868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETLONG(cilong, p); \
8888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilong != val) \
8898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	  goto bad; \
8908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCIENDP(opt, neg, class, val, vlen) \
8928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
8938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int i; \
8948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((len -= CILEN_CHAR + vlen) < 0) \
8958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
8978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
8988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != CILEN_CHAR + vlen || \
8998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype != opt) \
9008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
9018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cichar, p); \
9028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cichar != class) \
9038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
9048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	for (i = 0; i < vlen; ++i) { \
9058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETCHAR(cichar, p); \
9068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cichar != val[i]) \
9078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad; \
9088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} \
9098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru);
9128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
9138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      go->asyncmap);
9148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP);
9158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype);
9168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap,
9178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	       PPP_PAP);
9188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
9198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
9208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
9218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
9228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
9238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCISHORT(CI_MRRU, go->neg_mrru, go->mrru);
9248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCIVOID(CI_SSNHF, go->neg_ssnhf);
9258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class,
9268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      go->endpoint.value, go->endpoint.length);
9278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
9298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If there are any remaining CIs, then this packet is bad.
9308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
9318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (len != 0)
9328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	goto bad;
9338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return (1);
9348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectbad:
9358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    LCPDEBUG(("lcp_acki: received bad Ack!"));
9368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return (0);
9378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
9388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
9418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_nakci - Peer has sent a NAK for some of our CIs.
9428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This should not modify any state if the Nak is bad
9438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * or if LCP is in the OPENED state.
9448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
9458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Returns:
9468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *	0 - Nak was bad.
9478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *	1 - Nak was good.
9488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
9498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
9508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_nakci(f, p, len, treat_as_reject)
9518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
9528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
9538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
9548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int treat_as_reject;
9558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
9568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *go = &lcp_gotoptions[f->unit];
9578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *wo = &lcp_wantoptions[f->unit];
9588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char citype, cichar, *next;
9598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_short cishort;
9608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t cilong;
9618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options no;		/* options we've seen Naks for */
9628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options try;		/* options to request next time */
9638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int looped_back = 0;
9648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int cilen;
9658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    BZERO(&no, sizeof(no));
9678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    try = *go;
9688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
9708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Any Nak'd CIs must be in exactly the same order that we sent.
9718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Check packet length and CI length at each step.
9728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If we find any deviations, then this packet is bad.
9738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
9748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define NAKCIVOID(opt, neg) \
9758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
9768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_VOID && \
9778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_VOID && \
9788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
9798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_VOID; \
9808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(CILEN_VOID, p); \
9818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.neg = 1; \
9828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.neg = 0; \
9838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define NAKCICHAP(opt, neg, code) \
9858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
9868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_CHAP && \
9878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_CHAP && \
9888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
9898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_CHAP; \
9908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
9918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p); \
9928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cichar, p); \
9938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.neg = 1; \
9948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	code \
9958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define NAKCICHAR(opt, neg, code) \
9978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
9988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_CHAR && \
9998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_CHAR && \
10008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
10018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_CHAR; \
10028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
10038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cichar, p); \
10048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.neg = 1; \
10058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	code \
10068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define NAKCISHORT(opt, neg, code) \
10088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
10098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_SHORT && \
10108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_SHORT && \
10118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
10128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_SHORT; \
10138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
10148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p); \
10158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.neg = 1; \
10168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	code \
10178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define NAKCILONG(opt, neg, code) \
10198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
10208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_LONG && \
10218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_LONG && \
10228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
10238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_LONG; \
10248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
10258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETLONG(cilong, p); \
10268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.neg = 1; \
10278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	code \
10288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define NAKCILQR(opt, neg, code) \
10308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
10318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_LQR && \
10328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_LQR && \
10338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
10348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_LQR; \
10358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
10368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p); \
10378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETLONG(cilong, p); \
10388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.neg = 1; \
10398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	code \
10408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define NAKCIENDP(opt, neg) \
10428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
10438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_CHAR && \
10448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt && \
10458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] >= CILEN_CHAR && \
10468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] <= len) { \
10478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= p[1]; \
10488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(p[1], p); \
10498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.neg = 1; \
10508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.neg = 0; \
10518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
10548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * NOTE!  There must be no assignments to individual fields of *go in
10558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * the code below.  Any such assignment is a BUG!
10568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
10578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
10588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * We don't care if they want to send us smaller packets than
10598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * we want.  Therefore, accept any MRU less than what we asked for,
10608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * but then ignore the new value when setting the MRU in the kernel.
10618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If they send us a bigger MRU than what we asked, accept it, up to
10628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * the limit of the default MRU we'd get if we didn't negotiate.
10638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
10648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg_mru && go->mru != DEFMRU) {
10658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	NAKCISHORT(CI_MRU, neg_mru,
10668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   if (cishort <= wo->mru || cishort <= DEFMRU)
10678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		       try.mru = cishort;
10688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   );
10698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
10728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Add any characters they want to our (receive-side) asyncmap.
10738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
10748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) {
10758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	NAKCILONG(CI_ASYNCMAP, neg_asyncmap,
10768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		  try.asyncmap = go->asyncmap | cilong;
10778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		  );
10788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
10818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If they've nak'd our authentication-protocol, check whether
10828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * they are proposing a different protocol, or a different
10838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * hash algorithm for CHAP.
10848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
10858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if ((go->neg_chap || go->neg_upap || go->neg_eap)
10868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& len >= CILEN_SHORT
10878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) {
10888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cilen = p[1];
10898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= cilen;
10908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.neg_chap = go->neg_chap;
10918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.neg_upap = go->neg_upap;
10928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.neg_eap = go->neg_eap;
10938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p);
10948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p);
10958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cishort == PPP_PAP && cilen == CILEN_SHORT) {
10968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* If we were asking for EAP, then we need to stop that. */
10978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_eap)
10988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.neg_eap = 0;
10998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* If we were asking for CHAP, then we need to stop that. */
11018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    else if (go->neg_chap)
11028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.neg_chap = 0;
11038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
11048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * If we weren't asking for CHAP or EAP, then we were asking for
11058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * PAP, in which case this Nak is bad.
11068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
11078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    else
11088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
11098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {
11118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETCHAR(cichar, p);
11128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* Stop asking for EAP, if we were. */
11138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_eap) {
11148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.neg_eap = 0;
11158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* Try to set up to use their suggestion, if possible */
11168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (CHAP_CANDIGEST(go->chap_mdtype, cichar))
11178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    try.chap_mdtype = CHAP_MDTYPE_D(cichar);
11188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    } else if (go->neg_chap) {
11198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/*
11208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * We were asking for our preferred algorithm, they must
11218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * want something different.
11228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 */
11238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (cichar != CHAP_DIGEST(go->chap_mdtype)) {
11248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) {
11258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/* Use their suggestion if we support it ... */
11268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			try.chap_mdtype = CHAP_MDTYPE_D(cichar);
11278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    } else {
11288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/* ... otherwise, try our next-preferred algorithm. */
11298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			try.chap_mdtype &= ~(CHAP_MDTYPE(try.chap_mdtype));
11308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (try.chap_mdtype == MDTYPE_NONE) /* out of algos */
11318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    try.neg_chap = 0;
11328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
11338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} else {
11348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    /*
11358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     * Whoops, they Nak'd our algorithm of choice
11368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     * but then suggested it back to us.
11378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     */
11388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    goto bad;
11398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
11408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    } else {
11418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/*
11428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * Stop asking for PAP if we were asking for it.
11438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 */
11448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.neg_upap = 0;
11458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
11468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else {
11488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
11508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * If we were asking for EAP, and they're Conf-Naking EAP,
11518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * well, that's just strange.  Nobody should do that.
11528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
11538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cishort == PPP_EAP && cilen == CILEN_SHORT && go->neg_eap)
11548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		dbglog("Unexpected Conf-Nak for EAP");
11558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
11578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * We don't recognize what they're suggesting.
11588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * Stop asking for what we were asking for.
11598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
11608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_eap)
11618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.neg_eap = 0;
11628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    else if (go->neg_chap)
11638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.neg_chap = 0;
11648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    else
11658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.neg_upap = 0;
11668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p += cilen - CILEN_SHORT;
11678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
11688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
11698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
11718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If they can't cope with our link quality protocol, we'll have
11728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * to stop asking for LQR.  We haven't got any other protocol.
11738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If they Nak the reporting period, take their value XXX ?
11748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
11758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NAKCILQR(CI_QUALITY, neg_lqr,
11768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     if (cishort != PPP_LQR)
11778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 try.neg_lqr = 0;
11788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     else
11798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 try.lqr_period = cilong;
11808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     );
11818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
11838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Only implementing CBCP...not the rest of the callback options
11848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
11858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NAKCICHAR(CI_CALLBACK, neg_cbcp,
11868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project              try.neg_cbcp = 0;
11878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project              );
11888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
11908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Check for a looped-back line.
11918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
11928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,
11938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      try.magicnumber = magic();
11948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      looped_back = 1;
11958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      );
11968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
11988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Peer shouldn't send Nak for protocol compression or
11998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * address/control compression requests; they should send
12008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * a Reject instead.  If they send a Nak, treat it as a Reject.
12018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
12028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NAKCIVOID(CI_PCOMPRESSION, neg_pcompression);
12038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NAKCIVOID(CI_ACCOMPRESSION, neg_accompression);
12048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
12068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Nak for MRRU option - accept their value if it is smaller
12078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * than the one we want.
12088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
12098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg_mrru) {
12108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	NAKCISHORT(CI_MRRU, neg_mrru,
12118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   if (treat_as_reject)
12128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		       try.neg_mrru = 0;
12138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   else if (cishort <= wo->mrru)
12148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		       try.mrru = cishort;
12158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   );
12168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
12198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Nak for short sequence numbers shouldn't be sent, treat it
12208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * like a reject.
12218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
12228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NAKCIVOID(CI_SSNHF, neg_ssnhf);
12238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
12258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Nak of the endpoint discriminator option is not permitted,
12268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * treat it like a reject.
12278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
12288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NAKCIENDP(CI_EPDISC, neg_endpoint);
12298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
12318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * There may be remaining CIs, if the peer is requesting negotiation
12328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * on an option that we didn't include in our request packet.
12338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If we see an option that we requested, or one we've already seen
12348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * in this packet, then this packet is bad.
12358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If we wanted to respond by starting to negotiate on the requested
12368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * option(s), we could, but we don't, because except for the
12378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * authentication type and quality protocol, if we are not negotiating
12388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * an option, it is because we were told not to.
12398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * For the authentication type, the Nak from the peer means
12408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * `let me authenticate myself with you' which is a bit pointless.
12418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * For the quality protocol, the Nak means `ask me to send you quality
12428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * reports', but if we didn't ask for them, we don't want them.
12438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * An option we don't recognize represents the peer asking to
12448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * negotiate some option we don't support, so ignore it.
12458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
12468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while (len >= CILEN_VOID) {
12478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p);
12488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p);
12498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen < CILEN_VOID || (len -= cilen) < 0)
12508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad;
12518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	next = p + cilen - 2;
12528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	switch (citype) {
12548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_MRU:
12558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if ((go->neg_mru && go->mru != DEFMRU)
12568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		|| no.neg_mru || cilen != CILEN_SHORT)
12578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
12588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETSHORT(cishort, p);
12598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cishort < DEFMRU) {
12608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.neg_mru = 1;
12618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.mru = cishort;
12628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
12638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_ASYNCMAP:
12658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF)
12668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		|| no.neg_asyncmap || cilen != CILEN_LONG)
12678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
12688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_AUTHTYPE:
12708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap ||
12718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		go->neg_eap || no.neg_eap)
12728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
12738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_MAGICNUMBER:
12758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_magicnumber || no.neg_magicnumber ||
12768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen != CILEN_LONG)
12778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
12788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_PCOMPRESSION:
12808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_pcompression || no.neg_pcompression
12818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		|| cilen != CILEN_VOID)
12828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
12838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_ACCOMPRESSION:
12858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_accompression || no.neg_accompression
12868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		|| cilen != CILEN_VOID)
12878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
12888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_QUALITY:
12908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR)
12918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
12928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_MRRU:
12948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_mrru || no.neg_mrru || cilen != CILEN_SHORT)
12958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
12968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_SSNHF:
12988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_ssnhf || no.neg_ssnhf || cilen != CILEN_VOID)
12998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
13008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    try.neg_ssnhf = 1;
13018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
13028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_EPDISC:
13038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_endpoint || no.neg_endpoint || cilen < CILEN_CHAR)
13048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
13058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
13068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
13078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p = next;
13088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
13118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * OK, the Nak is good.  Now we can update state.
13128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If there are any options left we ignore them.
13138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
13148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->state != OPENED) {
13158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (looped_back) {
13168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (++try.numloops >= lcp_loopbackfail) {
13178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		notice("Serial line is looped back.");
13188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		status = EXIT_LOOPBACK;
13191286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		lcp_close(f->unit, "Loopback detected");
13208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
13218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else
13228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    try.numloops = 0;
13238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	*go = try;
13248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
13278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectbad:
13298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    LCPDEBUG(("lcp_nakci: received bad Nak!"));
13308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
13318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
13358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_rejci - Peer has Rejected some of our CIs.
13368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This should not modify any state if the Reject is bad
13378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * or if LCP is in the OPENED state.
13388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
13398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Returns:
13408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *	0 - Reject was bad.
13418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *	1 - Reject was good.
13428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
13438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
13448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_rejci(f, p, len)
13458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
13468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
13478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
13488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
13498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *go = &lcp_gotoptions[f->unit];
13508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char cichar;
13518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_short cishort;
13528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t cilong;
13538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options try;		/* options to request next time */
13548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    try = *go;
13568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
13588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Any Rejected CIs must be in exactly the same order that we sent.
13598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Check packet length and CI length at each step.
13608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If we find any deviations, then this packet is bad.
13618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
13628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define REJCIVOID(opt, neg) \
13638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
13648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_VOID && \
13658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_VOID && \
13668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
13678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_VOID; \
13688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(CILEN_VOID, p); \
13698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.neg = 0; \
13708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define REJCISHORT(opt, neg, val) \
13728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
13738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_SHORT && \
13748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_SHORT && \
13758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
13768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_SHORT; \
13778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
13788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p); \
13798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Check rejected value. */ \
13808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cishort != val) \
13818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
13828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.neg = 0; \
13838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define REJCICHAP(opt, neg, val) \
13858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
13868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_CHAP && \
13878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_CHAP && \
13888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
13898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_CHAP; \
13908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
13918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p); \
13928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cichar, p); \
13938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Check rejected value. */ \
13948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \
13958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
13968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.neg = 0; \
13978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.neg_eap = try.neg_upap = 0; \
13988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define REJCILONG(opt, neg, val) \
14008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
14018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_LONG && \
14028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_LONG && \
14038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
14048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_LONG; \
14058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
14068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETLONG(cilong, p); \
14078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Check rejected value. */ \
14088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilong != val) \
14098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
14108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.neg = 0; \
14118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
14128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define REJCILQR(opt, neg, val) \
14138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
14148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_LQR && \
14158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_LQR && \
14168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
14178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_LQR; \
14188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
14198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p); \
14208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETLONG(cilong, p); \
14218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Check rejected value. */ \
14228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cishort != PPP_LQR || cilong != val) \
14238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
14248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.neg = 0; \
14258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
14268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define REJCICBCP(opt, neg, val) \
14278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
14288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_CBCP && \
14298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_CBCP && \
14308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
14318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_CBCP; \
14328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
14338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cichar, p); \
14348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Check rejected value. */ \
14358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cichar != val) \
14368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
14378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.neg = 0; \
14388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
14398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define REJCIENDP(opt, neg, class, val, vlen) \
14408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
14418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_CHAR + vlen && \
14428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt && \
14438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_CHAR + vlen) { \
14448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int i; \
14458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_CHAR + vlen; \
14468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
14478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cichar, p); \
14488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cichar != class) \
14498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
14508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	for (i = 0; i < vlen; ++i) { \
14518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETCHAR(cichar, p); \
14528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cichar != val[i]) \
14538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad; \
14548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} \
14558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.neg = 0; \
14568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
14578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCISHORT(CI_MRU, neg_mru, go->mru);
14598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);
14608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCISHORT(CI_AUTHTYPE, neg_eap, PPP_EAP);
14618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!go->neg_eap) {
14628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	REJCICHAP(CI_AUTHTYPE, neg_chap, go->chap_mdtype);
14638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!go->neg_chap) {
14648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);
14658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
14668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
14678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);
14688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT);
14698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber);
14708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCIVOID(CI_PCOMPRESSION, neg_pcompression);
14718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCIVOID(CI_ACCOMPRESSION, neg_accompression);
14728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCISHORT(CI_MRRU, neg_mrru, go->mrru);
14738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCIVOID(CI_SSNHF, neg_ssnhf);
14748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCIENDP(CI_EPDISC, neg_endpoint, go->endpoint.class,
14758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      go->endpoint.value, go->endpoint.length);
14768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
14788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If there are any remaining CIs, then this packet is bad.
14798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
14808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (len != 0)
14818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	goto bad;
14828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
14838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Now we can update state.
14848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
14858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->state != OPENED)
14868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	*go = try;
14878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
14888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectbad:
14908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    LCPDEBUG(("lcp_rejci: received bad Reject!"));
14918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
14928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
14938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
14968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_reqci - Check the peer's requested CIs and send appropriate response.
14978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
14988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
14998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * appropriately.  If reject_if_disagree is non-zero, doesn't return
15008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * CONFNAK; returns CONFREJ if it can't return CONFACK.
15018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
15028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
15038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_reqci(f, inp, lenp, reject_if_disagree)
15048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
15058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *inp;		/* Requested CIs */
15068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int *lenp;			/* Length of requested CIs */
15078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int reject_if_disagree;
15088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
15098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *go = &lcp_gotoptions[f->unit];
15108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *ho = &lcp_hisoptions[f->unit];
15118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *ao = &lcp_allowoptions[f->unit];
15128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *cip, *next;		/* Pointer to current and next CIs */
15138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int cilen, citype, cichar;	/* Parsed len, type, char value */
15148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_short cishort;		/* Parsed short value */
15158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t cilong;		/* Parse long value */
15168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int rc = CONFACK;		/* Final packet return code */
15178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int orc;			/* Individual option return code */
15188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;			/* Pointer to next char to parse */
15198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *rejp;		/* Pointer to next char in reject frame */
15208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *nakp;		/* Pointer to next char in Nak frame */
15218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int l = *lenp;		/* Length left */
15228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
15248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Reset all his options.
15258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
15268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    BZERO(ho, sizeof(*ho));
15278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
15298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Process all his options.
15308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
15318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    next = inp;
15328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    nakp = nak_buffer;
15338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rejp = inp;
15348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while (l) {
15358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	orc = CONFACK;			/* Assume success */
15368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cip = p = next;			/* Remember begining of CI */
15378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (l < 2 ||			/* Not enough data for CI header or */
15388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p[1] < 2 ||			/*  CI length too small or */
15398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p[1] > l) {			/*  CI length too big? */
15408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LCPDEBUG(("lcp_reqci: bad CI length!"));
15418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    orc = CONFREJ;		/* Reject bad CI */
15428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    cilen = l;			/* Reject till end of packet */
15438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    l = 0;			/* Don't loop again */
15448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype = 0;
15458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto endswitch;
15468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
15478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p);		/* Parse CI type */
15488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p);		/* Parse CI length */
15498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	l -= cilen;			/* Adjust remaining length */
15508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	next += cilen;			/* Step to next CI */
15518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	switch (citype) {		/* Check CI type */
15538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_MRU:
15548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!ao->neg_mru ||		/* Allow option? */
15558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen != CILEN_SHORT) {	/* Check CI length */
15568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;		/* Reject CI */
15578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
15598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETSHORT(cishort, p);	/* Parse MRU */
15608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
15628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * He must be able to receive at least our minimum.
15638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * No need to check a maximum.  If he sends a large number,
15648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * we'll just ignore it.
15658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
15668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cishort < MINMRU) {
15678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFNAK;		/* Nak CI */
15688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CI_MRU, nakp);
15698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CILEN_SHORT, nakp);
15708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTSHORT(MINMRU, nakp);	/* Give him a hint */
15718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
15738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->neg_mru = 1;		/* Remember he sent MRU */
15748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->mru = cishort;		/* And remember value */
15758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
15768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_ASYNCMAP:
15788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!ao->neg_asyncmap ||
15798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen != CILEN_LONG) {
15808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
15818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
15838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETLONG(cilong, p);
15848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
15868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * Asyncmap must have set at least the bits
15878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * which are set in lcp_allowoptions[unit].asyncmap.
15888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
15898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if ((ao->asyncmap & ~cilong) != 0) {
15908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFNAK;
15918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CI_ASYNCMAP, nakp);
15928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CILEN_LONG, nakp);
15938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTLONG(ao->asyncmap | cilong, nakp);
15948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
15968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->neg_asyncmap = 1;
15978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->asyncmap = cilong;
15988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
15998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_AUTHTYPE:
16018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cilen < CILEN_SHORT ||
16028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		!(ao->neg_upap || ao->neg_chap || ao->neg_eap)) {
16038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/*
16048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * Reject the option if we're not willing to authenticate.
16058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 */
16068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		dbglog("No auth is possible");
16078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
16088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
16098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
16108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETSHORT(cishort, p);
16118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
16138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * Authtype must be PAP, CHAP, or EAP.
16148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     *
16158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * Note: if more than one of ao->neg_upap, ao->neg_chap, and
16168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * ao->neg_eap are set, and the peer sends a Configure-Request
16178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * with two or more authenticate-protocol requests, then we will
16188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * reject the second request.
16198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * Whether we end up doing CHAP, UPAP, or EAP depends then on
16208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * the ordering of the CIs in the peer's Configure-Request.
16218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project             */
16228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cishort == PPP_PAP) {
16248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* we've already accepted CHAP or EAP */
16258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (ho->neg_chap || ho->neg_eap ||
16268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    cilen != CILEN_SHORT) {
16278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE PAP, rejecting..."));
16288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    orc = CONFREJ;
16298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
16308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
16318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (!ao->neg_upap) {	/* we don't want to do PAP */
16328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    orc = CONFNAK;	/* NAK it and suggest CHAP or EAP */
16338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    PUTCHAR(CI_AUTHTYPE, nakp);
16348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (ao->neg_eap) {
16358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTCHAR(CILEN_SHORT, nakp);
16368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTSHORT(PPP_EAP, nakp);
16378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    } else {
16388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTCHAR(CILEN_CHAP, nakp);
16398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTSHORT(PPP_CHAP, nakp);
16408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
16418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
16428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
16438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
16448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ho->neg_upap = 1;
16458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
16468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
16478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cishort == PPP_CHAP) {
16488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* we've already accepted PAP or EAP */
16498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (ho->neg_upap || ho->neg_eap ||
16508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    cilen != CILEN_CHAP) {
16518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE CHAP, rejecting..."));
16528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    orc = CONFREJ;
16538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
16548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
16558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (!ao->neg_chap) {	/* we don't want to do CHAP */
16568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    orc = CONFNAK;	/* NAK it and suggest EAP or PAP */
16578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    PUTCHAR(CI_AUTHTYPE, nakp);
16588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    PUTCHAR(CILEN_SHORT, nakp);
16598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (ao->neg_eap) {
16608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTSHORT(PPP_EAP, nakp);
16618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    } else {
16628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTSHORT(PPP_PAP, nakp);
16638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
16648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
16658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
16668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		GETCHAR(cichar, p);	/* get digest type */
16678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (!(CHAP_CANDIGEST(ao->chap_mdtype, cichar))) {
16688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    /*
16698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     * We can't/won't do the requested type,
16708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     * suggest something else.
16718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     */
16728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    orc = CONFNAK;
16738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    PUTCHAR(CI_AUTHTYPE, nakp);
16748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    PUTCHAR(CILEN_CHAP, nakp);
16758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    PUTSHORT(PPP_CHAP, nakp);
16768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
16778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
16788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
16798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ho->chap_mdtype = CHAP_MDTYPE_D(cichar); /* save md type */
16808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ho->neg_chap = 1;
16818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
16828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
16838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cishort == PPP_EAP) {
16848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* we've already accepted CHAP or PAP */
16858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (ho->neg_chap || ho->neg_upap || cilen != CILEN_SHORT) {
16868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE EAP, rejecting..."));
16878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    orc = CONFREJ;
16888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
16898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
16908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (!ao->neg_eap) {	/* we don't want to do EAP */
16918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    orc = CONFNAK;	/* NAK it and suggest CHAP or PAP */
16928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    PUTCHAR(CI_AUTHTYPE, nakp);
16938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (ao->neg_chap) {
16948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTCHAR(CILEN_CHAP, nakp);
16958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTSHORT(PPP_CHAP, nakp);
16968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
16978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    } else {
16988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTCHAR(CILEN_SHORT, nakp);
16998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTSHORT(PPP_PAP, nakp);
17008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
17018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
17028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
17038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ho->neg_eap = 1;
17048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
17058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
17068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
17088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * We don't recognize the protocol they're asking for.
17098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * Nak it with something we're willing to do.
17108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * (At this point we know ao->neg_upap || ao->neg_chap ||
17118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * ao->neg_eap.)
17128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
17138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    orc = CONFNAK;
17148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    PUTCHAR(CI_AUTHTYPE, nakp);
17158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (ao->neg_eap) {
17168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CILEN_SHORT, nakp);
17178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTSHORT(PPP_EAP, nakp);
17188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    } else if (ao->neg_chap) {
17198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CILEN_CHAP, nakp);
17208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTSHORT(PPP_CHAP, nakp);
17218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
17228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    } else {
17238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CILEN_SHORT, nakp);
17248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTSHORT(PPP_PAP, nakp);
17258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
17268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
17278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_QUALITY:
17298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!ao->neg_lqr ||
17308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen != CILEN_LQR) {
17318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
17328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
17338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
17348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETSHORT(cishort, p);
17368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETLONG(cilong, p);
17378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
17398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * Check the protocol and the reporting period.
17408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * XXX When should we Nak this, and what with?
17418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
17428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cishort != PPP_LQR) {
17438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFNAK;
17448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CI_QUALITY, nakp);
17458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CILEN_LQR, nakp);
17468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTSHORT(PPP_LQR, nakp);
17478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTLONG(ao->lqr_period, nakp);
17488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
17498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
17508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
17518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_MAGICNUMBER:
17538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!(ao->neg_magicnumber || go->neg_magicnumber) ||
17548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen != CILEN_LONG) {
17558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
17568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
17578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
17588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETLONG(cilong, p);
17598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
17618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * He must have a different magic number.
17628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
17638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_magicnumber &&
17648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilong == go->magicnumber) {
17658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilong = magic();	/* Don't put magic() inside macro! */
17668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFNAK;
17678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CI_MAGICNUMBER, nakp);
17688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CILEN_LONG, nakp);
17698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTLONG(cilong, nakp);
17708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
17718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
17728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->neg_magicnumber = 1;
17738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->magicnumber = cilong;
17748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
17758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_PCOMPRESSION:
17788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!ao->neg_pcompression ||
17798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen != CILEN_VOID) {
17808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
17818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
17828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
17838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->neg_pcompression = 1;
17848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
17858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_ACCOMPRESSION:
17878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!ao->neg_accompression ||
17888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen != CILEN_VOID) {
17898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
17908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
17918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
17928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->neg_accompression = 1;
17938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
17948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_MRRU:
17968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!ao->neg_mrru || !multilink ||
17978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen != CILEN_SHORT) {
17988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
17998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
18008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
18018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETSHORT(cishort, p);
18038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* possibly should insist on a minimum/maximum MRRU here */
18048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->neg_mrru = 1;
18058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->mrru = cishort;
18068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
18078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_SSNHF:
18098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!ao->neg_ssnhf || !multilink ||
18108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen != CILEN_VOID) {
18118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
18128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
18138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
18148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->neg_ssnhf = 1;
18158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
18168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_EPDISC:
18188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!ao->neg_endpoint ||
18198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen < CILEN_CHAR ||
18208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen > CILEN_CHAR + MAX_ENDP_LEN) {
18218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
18228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
18238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
18248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETCHAR(cichar, p);
18258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    cilen -= CILEN_CHAR;
18268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->neg_endpoint = 1;
18278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->endpoint.class = cichar;
18288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->endpoint.length = cilen;
18298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    BCOPY(p, ho->endpoint.value, cilen);
18308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    INCPTR(cilen, p);
18318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
18328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	default:
18348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LCPDEBUG(("lcp_reqci: rcvd unknown option %d", citype));
18358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    orc = CONFREJ;
18368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
18378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
18388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectendswitch:
18408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (orc == CONFACK &&		/* Good CI */
18418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    rc != CONFACK)		/*  but prior CI wasnt? */
18428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;			/* Don't send this one */
18438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (orc == CONFNAK) {		/* Nak this CI? */
18458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (reject_if_disagree	/* Getting fed up with sending NAKs? */
18468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		&& citype != CI_MAGICNUMBER) {
18478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;		/* Get tough if so */
18488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    } else {
18498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (rc == CONFREJ)	/* Rejecting prior CI? */
18508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    continue;		/* Don't send this one */
18518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		rc = CONFNAK;
18528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
18538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
18548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (orc == CONFREJ) {		/* Reject this CI */
18558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    rc = CONFREJ;
18568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cip != rejp)		/* Need to move rejected CI? */
18578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		BCOPY(cip, rejp, cilen); /* Move it */
18588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    INCPTR(cilen, rejp);	/* Update output pointer */
18598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
18608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
18618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
18638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If we wanted to send additional NAKs (for unsent CIs), the
18648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * code would go here.  The extra NAKs would go at *nakp.
18658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * At present there are no cases where we want to ask the
18668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * peer to negotiate an option.
18678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
18688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    switch (rc) {
18708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFACK:
18718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	*lenp = next - inp;
18728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
18738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFNAK:
18748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
18758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Copy the Nak'd options from the nak_buffer to the caller's buffer.
18768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
18778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	*lenp = nakp - nak_buffer;
18788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	BCOPY(nak_buffer, inp, *lenp);
18798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
18808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFREJ:
18818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	*lenp = rejp - inp;
18828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
18838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
18848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    LCPDEBUG(("lcp_reqci: returning CONF%s.", CODENAME(rc)));
18868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return (rc);			/* Return final code */
18878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
18888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
18918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_up - LCP has come UP.
18928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
18938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
18948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_up(f)
18958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
18968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
18978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *wo = &lcp_wantoptions[f->unit];
18988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *ho = &lcp_hisoptions[f->unit];
18998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *go = &lcp_gotoptions[f->unit];
19008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *ao = &lcp_allowoptions[f->unit];
19018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int mtu, mru;
19028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!go->neg_magicnumber)
19048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	go->magicnumber = 0;
19058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!ho->neg_magicnumber)
19068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ho->magicnumber = 0;
19078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
19098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Set our MTU to the smaller of the MTU we wanted and
19108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * the MRU our peer wanted.  If we negotiated an MRU,
19118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * set our MRU to the larger of value we wanted and
19128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * the value we got in the negotiation.
19138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Note on the MTU: the link MTU can be the MRU the peer wanted,
19148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * the interface MTU is set to the lowest of that, the
19158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * MTU we want to use, and our link MRU.
19168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
19178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    mtu = ho->neg_mru? ho->mru: PPP_MRU;
19188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU;
19198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef HAVE_MULTILINK
19208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!(multilink && go->neg_mrru && ho->neg_mrru))
19218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* HAVE_MULTILINK */
19228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	netif_set_mtu(f->unit, MIN(MIN(mtu, mru), ao->mru));
19238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ppp_send_config(f->unit, mtu,
19248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    (ho->neg_asyncmap? ho->asyncmap: 0xffffffff),
19258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    ho->neg_pcompression, ho->neg_accompression);
19268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ppp_recv_config(f->unit, mru,
19278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    (lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff),
19288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    go->neg_pcompression, go->neg_accompression);
19298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ho->neg_mru)
19318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	peer_mru[f->unit] = ho->mru;
19328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_echo_lowerup(f->unit);  /* Enable echo messages */
19348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    link_established(f->unit);
19368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
19378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
19408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_down - LCP has gone DOWN.
19418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
19428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Alert other protocols.
19438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
19448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
19458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_down(f)
19468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
19478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
19488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *go = &lcp_gotoptions[f->unit];
19498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_echo_lowerdown(f->unit);
19518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    link_down(f->unit);
19538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ppp_send_config(f->unit, PPP_MRU, 0xffffffff, 0, 0);
19558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ppp_recv_config(f->unit, PPP_MRU,
19568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    (go->neg_asyncmap? go->asyncmap: 0xffffffff),
19578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    go->neg_pcompression, go->neg_accompression);
19588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    peer_mru[f->unit] = PPP_MRU;
19598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
19608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
19638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_starting - LCP needs the lower layer up.
19648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
19658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
19668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_starting(f)
19678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
19688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
19698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    link_required(f->unit);
19708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
19718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
19748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_finished - LCP has finished with the lower layer.
19758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
19768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
19778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_finished(f)
19788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
19798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
19808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    link_terminated(f->unit);
19818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
19828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
19858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_printpkt - print the contents of an LCP packet.
19868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
19878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char *lcp_codenames[] = {
19888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    "ConfReq", "ConfAck", "ConfNak", "ConfRej",
19898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    "TermReq", "TermAck", "CodeRej", "ProtRej",
19901286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    "EchoReq", "EchoRep", "DiscReq", "Ident",
19911286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    "TimeRem"
19928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
19938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
19958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_printpkt(p, plen, printer, arg)
19968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
19978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int plen;
19988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    void (*printer) __P((void *, char *, ...));
19998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    void *arg;
20008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
20018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int code, id, len, olen, i;
20028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *pstart, *optend;
20038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_short cishort;
20048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t cilong;
20058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (plen < HEADERLEN)
20078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
20088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pstart = p;
20098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    GETCHAR(code, p);
20108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    GETCHAR(id, p);
20118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    GETSHORT(len, p);
20128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (len < HEADERLEN || len > plen)
20138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
20148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *))
20168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	printer(arg, " %s", lcp_codenames[code-1]);
20178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    else
20188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	printer(arg, " code=0x%x", code);
20198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    printer(arg, " id=0x%x", id);
20208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    len -= HEADERLEN;
20218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    switch (code) {
20228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFREQ:
20238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFACK:
20248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFNAK:
20258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFREJ:
20268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* print option list */
20278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	while (len >= 2) {
20288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETCHAR(code, p);
20298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETCHAR(olen, p);
20308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p -= 2;
20318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (olen < 2 || olen > len) {
20328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
20338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
20348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    printer(arg, " <");
20358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    len -= olen;
20368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    optend = p + olen;
20378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    switch (code) {
20388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_MRU:
20398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen == CILEN_SHORT) {
20408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
20418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    GETSHORT(cishort, p);
20428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "mru %d", cishort);
20438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
20448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
20458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_ASYNCMAP:
20468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen == CILEN_LONG) {
20478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
20488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    GETLONG(cilong, p);
20498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "asyncmap 0x%x", cilong);
20508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
20518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
20528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_AUTHTYPE:
20538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen >= CILEN_SHORT) {
20548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
20558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "auth ");
20568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    GETSHORT(cishort, p);
20578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    switch (cishort) {
20588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    case PPP_PAP:
20598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, "pap");
20608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
20618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    case PPP_CHAP:
20628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, "chap");
20638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (p < optend) {
20648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    switch (*p) {
20658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    case CHAP_MD5:
20668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " MD5");
20678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				++p;
20688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
20698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    case CHAP_MICROSOFT:
20708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " MS");
20718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				++p;
20728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
20738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    case CHAP_MICROSOFT_V2:
20758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " MS-v2");
20768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				++p;
20778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
20788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    }
20798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
20808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
20818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    case PPP_EAP:
20828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, "eap");
20838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
20848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    default:
20858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, "0x%x", cishort);
20868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
20878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
20888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
20898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_QUALITY:
20908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen >= CILEN_SHORT) {
20918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
20928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "quality ");
20938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    GETSHORT(cishort, p);
20948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    switch (cishort) {
20958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    case PPP_LQR:
20968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, "lqr");
20978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
20988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    default:
20998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, "0x%x", cishort);
21008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
21018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
21028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
21038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_CALLBACK:
21048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen >= CILEN_CHAR) {
21058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
21068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "callback ");
21078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    GETCHAR(cishort, p);
21088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    switch (cishort) {
21098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    case CBCP_OPT:
21108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, "CBCP");
21118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
21128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    default:
21138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, "0x%x", cishort);
21148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
21158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
21168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
21178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_MAGICNUMBER:
21188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen == CILEN_LONG) {
21198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
21208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    GETLONG(cilong, p);
21218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "magic 0x%x", cilong);
21228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
21238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
21248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_PCOMPRESSION:
21258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen == CILEN_VOID) {
21268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
21278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "pcomp");
21288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
21298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
21308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_ACCOMPRESSION:
21318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen == CILEN_VOID) {
21328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
21338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "accomp");
21348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
21358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
21368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_MRRU:
21378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen == CILEN_SHORT) {
21388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
21398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    GETSHORT(cishort, p);
21408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "mrru %d", cishort);
21418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
21428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
21438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_SSNHF:
21448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen == CILEN_VOID) {
21458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
21468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "ssnhf");
21478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
21488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
21498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_EPDISC:
21508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef HAVE_MULTILINK
21518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen >= CILEN_CHAR) {
21528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    struct epdisc epd;
21538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
21548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    GETCHAR(epd.class, p);
21558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    epd.length = olen - CILEN_CHAR;
21568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (epd.length > MAX_ENDP_LEN)
21578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			epd.length = MAX_ENDP_LEN;
21588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (epd.length > 0) {
21598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			BCOPY(p, epd.value, epd.length);
21608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			p += epd.length;
21618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
21628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "endpoint [%s]", epdisc_to_str(&epd));
21638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
21648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#else
21658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		printer(arg, "endpoint");
21668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
21678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
21688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
21698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    while (p < optend) {
21708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		GETCHAR(code, p);
21718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		printer(arg, " %.2x", code);
21728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
21738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    printer(arg, ">");
21748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
21758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
21768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case TERMACK:
21788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case TERMREQ:
21798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len > 0 && *p >= ' ' && *p < 0x7f) {
21808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    printer(arg, " ");
21818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    print_string((char *)p, len, printer, arg);
21828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p += len;
21838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    len = 0;
21848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
21858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
21868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case ECHOREQ:
21888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case ECHOREP:
21898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case DISCREQ:
21908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len >= 4) {
21918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETLONG(cilong, p);
21928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    printer(arg, " magic=0x%x", cilong);
21938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    len -= 4;
21948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
21958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
21961286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley
21971286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    case IDENTIF:
21981286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    case TIMEREM:
21991286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	if (len >= 4) {
22001286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	    GETLONG(cilong, p);
22011286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	    printer(arg, " magic=0x%x", cilong);
22021286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	    len -= 4;
22031286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	}
22041286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	if (code == TIMEREM) {
22051286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	    if (len < 4)
22061286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		break;
22071286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	    GETLONG(cilong, p);
22081286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	    printer(arg, " seconds=%u", cilong);
22091286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	    len -= 4;
22101286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	}
22111286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	if (len > 0) {
22121286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	    printer(arg, " ");
22131286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	    print_string((char *)p, len, printer, arg);
22141286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	    p += len;
22151286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	    len = 0;
22161286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	}
22171286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	break;
22188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
22198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* print the rest of the bytes in the packet */
22218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (i = 0; i < len && i < 32; ++i) {
22228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(code, p);
22238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	printer(arg, " %.2x", code);
22248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
22258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (i < len) {
22268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	printer(arg, " ...");
22278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p += len - i;
22288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
22298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return p - pstart;
22318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
22328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
22348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Time to shut down the link because there is nothing out there.
22358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
22368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic
22388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid LcpLinkFailure (f)
22398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
22408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
22418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->state == OPENED) {
22428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	info("No response to %d echo-requests", lcp_echos_pending);
22438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        notice("Serial link appears to be disconnected.");
22448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	status = EXIT_PEER_DEAD;
22451286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	lcp_close(f->unit, "Peer not responding");
22468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
22478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
22488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
22508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Timer expired for the LCP echo requests from this process.
22518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
22528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
22548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectLcpEchoCheck (f)
22558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
22568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
22578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    LcpSendEchoRequest (f);
22588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->state != OPENED)
22598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
22608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
22628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Start the timer for the next interval.
22638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
22648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (lcp_echo_timer_running)
22658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("assertion lcp_echo_timer_running==0 failed");
22668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval);
22678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_echo_timer_running = 1;
22688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
22698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
22718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * LcpEchoTimeout - Timer expired on the LCP echo
22728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
22738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
22758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectLcpEchoTimeout (arg)
22768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    void *arg;
22778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
22788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (lcp_echo_timer_running != 0) {
22798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        lcp_echo_timer_running = 0;
22808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        LcpEchoCheck ((fsm *) arg);
22818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
22828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
22838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
22858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * LcpEchoReply - LCP has received a reply to the echo
22868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
22878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
22898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_received_echo_reply (f, id, inp, len)
22908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
22918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int id;
22928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *inp;
22938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
22948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
22958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t magic;
22968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Check the magic number - don't count replies from ourselves. */
22988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (len < 4) {
22998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	dbglog("lcp: received short Echo-Reply, length %d", len);
23008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
23018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
23028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    GETLONG(magic, inp);
23038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (lcp_gotoptions[f->unit].neg_magicnumber
23048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& magic == lcp_gotoptions[f->unit].magicnumber) {
23058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("appear to have received our own echo-reply!");
23068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
23078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
23088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Reset the number of outstanding echo frames */
23108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_echos_pending = 0;
23118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
23128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
23148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * LcpSendEchoRequest - Send an echo request frame to the peer
23158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
23168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
23188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectLcpSendEchoRequest (f)
23198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
23208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
23218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t lcp_magic;
23228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char pkt[4], *pktp;
23238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
23258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Detect the failure of the peer at this point.
23268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
23278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (lcp_echo_fails != 0) {
23288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        if (lcp_echos_pending >= lcp_echo_fails) {
23298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project            LcpLinkFailure(f);
23308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    lcp_echos_pending = 0;
23318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
23328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
23338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
23358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Make and send the echo request frame.
23368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
23378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->state == OPENED) {
23388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        lcp_magic = lcp_gotoptions[f->unit].magicnumber;
23398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	pktp = pkt;
23408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTLONG(lcp_magic, pktp);
23418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        fsm_sdata(f, ECHOREQ, lcp_echo_number++ & 0xFF, pkt, pktp - pkt);
23428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	++lcp_echos_pending;
23438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
23448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
23458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
23478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_echo_lowerup - Start the timer for the LCP frame
23488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
23498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
23518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_echo_lowerup (unit)
23528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
23538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
23548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f = &lcp_fsm[unit];
23558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Clear the parameters for generating echo frames */
23578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_echos_pending      = 0;
23588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_echo_number        = 0;
23598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_echo_timer_running = 0;
23608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* If a timeout interval is specified then start the timer */
23628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (lcp_echo_interval != 0)
23638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        LcpEchoCheck (f);
23648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
23658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
23678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_echo_lowerdown - Stop the timer for the LCP frame
23688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
23698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
23718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_echo_lowerdown (unit)
23728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
23738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
23748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f = &lcp_fsm[unit];
23758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (lcp_echo_timer_running != 0) {
23778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        UNTIMEOUT (LcpEchoTimeout, f);
23788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        lcp_echo_timer_running = 0;
23798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
23808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
2381