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
438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define RCSID	"$Id: lcp.c,v 1.74 2004/11/13 02:28:15 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];
4008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (phase != PHASE_DEAD && phase != PHASE_MASTER)
4028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	new_phase(PHASE_TERMINATE);
4038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) {
4048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
4058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * This action is not strictly according to the FSM in RFC1548,
4068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * but it does mean that the program terminates if you do a
4078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * lcp_close() in passive/silent mode when a connection hasn't
4088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * been established.
4098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
4108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	f->state = CLOSED;
4118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	lcp_finished(f);
4128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else
4148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fsm_close(f, reason);
4158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_lowerup - The lower layer is up.
4208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
4228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_lowerup(unit)
4238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
4248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *wo = &lcp_wantoptions[unit];
4268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f = &lcp_fsm[unit];
4278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
4298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Don't use A/C or protocol compression on transmission,
4308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * but accept A/C and protocol compressed packets
4318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * if we are going to ask for A/C and protocol compression.
4328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
4338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0) < 0
4348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	|| ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff),
4358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			   wo->neg_pcompression, wo->neg_accompression) < 0)
4368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return;
4378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    peer_mru[unit] = PPP_MRU;
4388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (listen_time != 0) {
4408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	f->flags |= DELAYED_UP;
4418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	timeout(lcp_delayed_up, f, 0, listen_time * 1000);
4428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else
4438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fsm_lowerup(f);
4448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_lowerdown - The lower layer is down.
4498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
4518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_lowerdown(unit)
4528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
4538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f = &lcp_fsm[unit];
4558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->flags & DELAYED_UP)
4578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	f->flags &= ~DELAYED_UP;
4588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    else
4598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fsm_lowerdown(&lcp_fsm[unit]);
4608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_delayed_up - Bring the lower layer up now.
4658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
4678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_delayed_up(arg)
4688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    void *arg;
4698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f = arg;
4718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->flags & DELAYED_UP) {
4738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	f->flags &= ~DELAYED_UP;
4748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fsm_lowerup(f);
4758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
4768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_input - Input LCP packet.
4818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
4838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_input(unit, p, len)
4848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
4858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
4868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
4878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f = &lcp_fsm[unit];
4898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->flags & DELAYED_UP) {
4918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	f->flags &= ~DELAYED_UP;
4928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fsm_lowerup(f);
4938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
4948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_input(f, p, len);
4958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_extcode - Handle a LCP-specific code.
5008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
5018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
5028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_extcode(f, code, id, inp, len)
5038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
5048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int code, id;
5058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *inp;
5068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
5078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
5088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *magp;
5098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    switch( code ){
5118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case PROTREJ:
5128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	lcp_rprotrej(f, inp, len);
5138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
5148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case ECHOREQ:
5168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (f->state != OPENED)
5178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
5188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	magp = inp;
5198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);
5208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fsm_sdata(f, ECHOREP, id, inp, len);
5218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
5228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case ECHOREP:
5248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	lcp_received_echo_reply(f, id, inp, len);
5258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
5268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case DISCREQ:
5288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
5298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    default:
5318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
5328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
5338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
5348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
5358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
5388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_rprotrej - Receive an Protocol-Reject.
5398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
5408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Figure out which protocol is rejected and inform it.
5418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
5428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
5438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_rprotrej(f, inp, len)
5448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
5458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *inp;
5468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
5478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
5488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int i;
5498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct protent *protp;
5508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_short prot;
5518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (len < 2) {
5538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	LCPDEBUG(("lcp_rprotrej: Rcvd short Protocol-Reject packet!"));
5548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
5558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
5568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    GETSHORT(prot, inp);
5588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
5608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Protocol-Reject packets received in any state other than the LCP
5618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * OPENED state SHOULD be silently discarded.
5628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
5638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if( f->state != OPENED ){
5648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	LCPDEBUG(("Protocol-Reject discarded: LCP in state %d", f->state));
5658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
5668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
5678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
5698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Upcall the proper Protocol-Reject routine.
5708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
5718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (i = 0; (protp = protocols[i]) != NULL; ++i)
5728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (protp->protocol == prot && protp->enabled_flag) {
5738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    (*protp->protrej)(f->unit);
5748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return;
5758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
5768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    warn("Protocol-Reject for unsupported protocol 0x%x", prot);
5788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
5798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
5828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_protrej - A Protocol-Reject was received.
5838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
5848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*ARGSUSED*/
5858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
5868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_protrej(unit)
5878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
5888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
5898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
5908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Can't reject LCP!
5918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
5928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    error("Received Protocol-Reject for LCP!");
5938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_protreject(&lcp_fsm[unit]);
5948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
5958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
5988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_sprotrej - Send a Protocol-Reject for some protocol.
5998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
6008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
6018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_sprotrej(unit, p, len)
6028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
6038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
6048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
6058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
6068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
6078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Send back the protocol and the information field of the
6088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * rejected packet.  We only get here if LCP is in the OPENED state.
6098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
6108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    p += 2;
6118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    len -= 2;
6128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id,
6148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      p, len);
6158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
6168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
6198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_resetci - Reset our CI.
6208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
6218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
6228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_resetci(f)
6238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
6248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
6258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *wo = &lcp_wantoptions[f->unit];
6268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *go = &lcp_gotoptions[f->unit];
6278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *ao = &lcp_allowoptions[f->unit];
6288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    wo->magicnumber = magic();
6308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    wo->numloops = 0;
6318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    *go = *wo;
6328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!multilink) {
6338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	go->neg_mrru = 0;
6348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	go->neg_ssnhf = 0;
6358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	go->neg_endpoint = 0;
6368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (noendpoint)
6388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ao->neg_endpoint = 0;
6398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    peer_mru[f->unit] = PPP_MRU;
6408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    auth_reset(f->unit);
6418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
6428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
6458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_cilen - Return length of our CI.
6468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
6478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
6488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_cilen(f)
6498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
6508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
6518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *go = &lcp_gotoptions[f->unit];
6528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define LENCIVOID(neg)	((neg) ? CILEN_VOID : 0)
6548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define LENCICHAP(neg)	((neg) ? CILEN_CHAP : 0)
6558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define LENCISHORT(neg)	((neg) ? CILEN_SHORT : 0)
6568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define LENCILONG(neg)	((neg) ? CILEN_LONG : 0)
6578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define LENCILQR(neg)	((neg) ? CILEN_LQR: 0)
6588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define LENCICBCP(neg)	((neg) ? CILEN_CBCP: 0)
6598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
6608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * NB: we only ask for one of CHAP, UPAP, or EAP, even if we will
6618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * accept more than one.  We prefer EAP first, then CHAP, then
6628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * PAP.
6638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
6648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return (LENCISHORT(go->neg_mru && go->mru != DEFMRU) +
6658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) +
6668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCISHORT(go->neg_eap) +
6678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCICHAP(!go->neg_eap && go->neg_chap) +
6688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCISHORT(!go->neg_eap && !go->neg_chap && go->neg_upap) +
6698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCILQR(go->neg_lqr) +
6708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCICBCP(go->neg_cbcp) +
6718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCILONG(go->neg_magicnumber) +
6728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCIVOID(go->neg_pcompression) +
6738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCIVOID(go->neg_accompression) +
6748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCISHORT(go->neg_mrru) +
6758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LENCIVOID(go->neg_ssnhf) +
6768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    (go->neg_endpoint? CILEN_CHAR + go->endpoint.length: 0));
6778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
6788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
6818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_addci - Add our desired CIs to a packet.
6828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
6838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
6848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_addci(f, ucp, lenp)
6858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
6868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *ucp;
6878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int *lenp;
6888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
6898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *go = &lcp_gotoptions[f->unit];
6908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *start_ucp = ucp;
6918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ADDCIVOID(opt, neg) \
6938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
6948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(opt, ucp); \
6958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(CILEN_VOID, ucp); \
6968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ADDCISHORT(opt, neg, val) \
6988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
6998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(opt, ucp); \
7008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(CILEN_SHORT, ucp); \
7018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTSHORT(val, ucp); \
7028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ADDCICHAP(opt, neg, val) \
7048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
7058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR((opt), ucp); \
7068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(CILEN_CHAP, ucp); \
7078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTSHORT(PPP_CHAP, ucp); \
7088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR((CHAP_DIGEST(val)), ucp); \
7098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ADDCILONG(opt, neg, val) \
7118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
7128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(opt, ucp); \
7138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(CILEN_LONG, ucp); \
7148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTLONG(val, ucp); \
7158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ADDCILQR(opt, neg, val) \
7178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
7188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(opt, ucp); \
7198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(CILEN_LQR, ucp); \
7208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTSHORT(PPP_LQR, ucp); \
7218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTLONG(val, ucp); \
7228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ADDCICHAR(opt, neg, val) \
7248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
7258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(opt, ucp); \
7268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(CILEN_CHAR, ucp); \
7278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(val, ucp); \
7288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ADDCIENDP(opt, neg, class, val, len) \
7308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
7318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int i; \
7328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(opt, ucp); \
7338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(CILEN_CHAR + len, ucp); \
7348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(class, ucp); \
7358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	for (i = 0; i < len; ++i) \
7368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    PUTCHAR(val[i], ucp); \
7378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru);
7408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
7418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      go->asyncmap);
7428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP);
7438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype);
7448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap,
7458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	       PPP_PAP);
7468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
7478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
7488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
7498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
7508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
7518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCISHORT(CI_MRRU, go->neg_mrru, go->mrru);
7528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCIVOID(CI_SSNHF, go->neg_ssnhf);
7538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ADDCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class,
7548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      go->endpoint.value, go->endpoint.length);
7558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ucp - start_ucp != *lenp) {
7578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* this should never happen, because peer_mtu should be 1500 */
7588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Bug in lcp_addci: wrong length");
7598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
7618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
7648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_ackci - Ack our CIs.
7658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This should not modify any state if the Ack is bad.
7668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
7678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Returns:
7688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *	0 - Ack was bad.
7698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *	1 - Ack was good.
7708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
7718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
7728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_ackci(f, p, len)
7738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
7748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
7758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
7768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
7778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *go = &lcp_gotoptions[f->unit];
7788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char cilen, citype, cichar;
7798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_short cishort;
7808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t cilong;
7818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
7838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * CIs must be in exactly the same order that we sent.
7848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Check packet length and CI length at each step.
7858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If we find any deviations, then this packet is bad.
7868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
7878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCIVOID(opt, neg) \
7888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
7898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((len -= CILEN_VOID) < 0) \
7908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
7918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
7928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
7938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != CILEN_VOID || \
7948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype != opt) \
7958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
7968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCISHORT(opt, neg, val) \
7988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
7998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((len -= CILEN_SHORT) < 0) \
8008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
8028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
8038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != CILEN_SHORT || \
8048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype != opt) \
8058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p); \
8078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cishort != val) \
8088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCICHAR(opt, neg, val) \
8118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
8128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((len -= CILEN_CHAR) < 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_CHAR || \
8178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype != opt) \
8188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cichar, p); \
8208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cichar != val) \
8218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCICHAP(opt, neg, val) \
8248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
8258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((len -= CILEN_CHAP) < 0) \
8268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
8288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
8298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != CILEN_CHAP || \
8308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype != (opt)) \
8318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p); \
8338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cishort != PPP_CHAP) \
8348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cichar, p); \
8368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cichar != (CHAP_DIGEST(val))) \
8378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	  goto bad; \
8388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCILONG(opt, neg, val) \
8408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
8418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((len -= CILEN_LONG) < 0) \
8428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
8448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
8458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != CILEN_LONG || \
8468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype != opt) \
8478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETLONG(cilong, p); \
8498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilong != val) \
8508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCILQR(opt, neg, val) \
8538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
8548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((len -= CILEN_LQR) < 0) \
8558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
8578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
8588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != CILEN_LQR || \
8598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype != opt) \
8608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p); \
8628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cishort != PPP_LQR) \
8638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETLONG(cilong, p); \
8658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilong != val) \
8668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	  goto bad; \
8678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCIENDP(opt, neg, class, val, vlen) \
8698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
8708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int i; \
8718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((len -= CILEN_CHAR + vlen) < 0) \
8728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
8748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
8758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != CILEN_CHAR + vlen || \
8768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype != opt) \
8778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cichar, p); \
8798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cichar != class) \
8808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
8818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	for (i = 0; i < vlen; ++i) { \
8828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETCHAR(cichar, p); \
8838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cichar != val[i]) \
8848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad; \
8858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} \
8868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru);
8898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
8908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      go->asyncmap);
8918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP);
8928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype);
8938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap,
8948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	       PPP_PAP);
8958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
8968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
8978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
8988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
8998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
9008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCISHORT(CI_MRRU, go->neg_mrru, go->mrru);
9018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCIVOID(CI_SSNHF, go->neg_ssnhf);
9028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ACKCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class,
9038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      go->endpoint.value, go->endpoint.length);
9048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
9068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If there are any remaining CIs, then this packet is bad.
9078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
9088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (len != 0)
9098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	goto bad;
9108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return (1);
9118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectbad:
9128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    LCPDEBUG(("lcp_acki: received bad Ack!"));
9138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return (0);
9148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
9158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
9188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_nakci - Peer has sent a NAK for some of our CIs.
9198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This should not modify any state if the Nak is bad
9208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * or if LCP is in the OPENED state.
9218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
9228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Returns:
9238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *	0 - Nak was bad.
9248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *	1 - Nak was good.
9258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
9268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
9278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_nakci(f, p, len, treat_as_reject)
9288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
9298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
9308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
9318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int treat_as_reject;
9328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
9338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *go = &lcp_gotoptions[f->unit];
9348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *wo = &lcp_wantoptions[f->unit];
9358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char citype, cichar, *next;
9368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_short cishort;
9378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t cilong;
9388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options no;		/* options we've seen Naks for */
9398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options try;		/* options to request next time */
9408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int looped_back = 0;
9418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int cilen;
9428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    BZERO(&no, sizeof(no));
9448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    try = *go;
9458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
9478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Any Nak'd CIs must be in exactly the same order that we sent.
9488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Check packet length and CI length at each step.
9498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If we find any deviations, then this packet is bad.
9508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
9518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define NAKCIVOID(opt, neg) \
9528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
9538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_VOID && \
9548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_VOID && \
9558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
9568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_VOID; \
9578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(CILEN_VOID, p); \
9588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.neg = 1; \
9598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.neg = 0; \
9608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define NAKCICHAP(opt, neg, code) \
9628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
9638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_CHAP && \
9648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_CHAP && \
9658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
9668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_CHAP; \
9678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
9688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p); \
9698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cichar, p); \
9708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.neg = 1; \
9718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	code \
9728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define NAKCICHAR(opt, neg, code) \
9748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
9758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_CHAR && \
9768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_CHAR && \
9778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
9788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_CHAR; \
9798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
9808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cichar, p); \
9818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.neg = 1; \
9828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	code \
9838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define NAKCISHORT(opt, neg, code) \
9858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
9868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_SHORT && \
9878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_SHORT && \
9888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
9898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_SHORT; \
9908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
9918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p); \
9928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.neg = 1; \
9938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	code \
9948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define NAKCILONG(opt, neg, code) \
9968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
9978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_LONG && \
9988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_LONG && \
9998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
10008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_LONG; \
10018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
10028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETLONG(cilong, p); \
10038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.neg = 1; \
10048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	code \
10058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define NAKCILQR(opt, neg, code) \
10078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
10088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_LQR && \
10098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_LQR && \
10108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
10118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_LQR; \
10128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
10138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p); \
10148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETLONG(cilong, 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 NAKCIENDP(opt, neg) \
10198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
10208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_CHAR && \
10218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt && \
10228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] >= CILEN_CHAR && \
10238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] <= len) { \
10248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= p[1]; \
10258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(p[1], p); \
10268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.neg = 1; \
10278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.neg = 0; \
10288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
10318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * NOTE!  There must be no assignments to individual fields of *go in
10328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * the code below.  Any such assignment is a BUG!
10338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
10348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
10358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * We don't care if they want to send us smaller packets than
10368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * we want.  Therefore, accept any MRU less than what we asked for,
10378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * but then ignore the new value when setting the MRU in the kernel.
10388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If they send us a bigger MRU than what we asked, accept it, up to
10398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * the limit of the default MRU we'd get if we didn't negotiate.
10408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
10418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg_mru && go->mru != DEFMRU) {
10428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	NAKCISHORT(CI_MRU, neg_mru,
10438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   if (cishort <= wo->mru || cishort <= DEFMRU)
10448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		       try.mru = cishort;
10458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   );
10468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
10498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Add any characters they want to our (receive-side) asyncmap.
10508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
10518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) {
10528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	NAKCILONG(CI_ASYNCMAP, neg_asyncmap,
10538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		  try.asyncmap = go->asyncmap | cilong;
10548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		  );
10558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
10588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If they've nak'd our authentication-protocol, check whether
10598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * they are proposing a different protocol, or a different
10608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * hash algorithm for CHAP.
10618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
10628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if ((go->neg_chap || go->neg_upap || go->neg_eap)
10638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& len >= CILEN_SHORT
10648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) {
10658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cilen = p[1];
10668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= cilen;
10678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.neg_chap = go->neg_chap;
10688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.neg_upap = go->neg_upap;
10698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	no.neg_eap = go->neg_eap;
10708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p);
10718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p);
10728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cishort == PPP_PAP && cilen == CILEN_SHORT) {
10738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* If we were asking for EAP, then we need to stop that. */
10748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_eap)
10758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.neg_eap = 0;
10768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* If we were asking for CHAP, then we need to stop that. */
10788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    else if (go->neg_chap)
10798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.neg_chap = 0;
10808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
10818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * If we weren't asking for CHAP or EAP, then we were asking for
10828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * PAP, in which case this Nak is bad.
10838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
10848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    else
10858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
10868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {
10888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETCHAR(cichar, p);
10898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* Stop asking for EAP, if we were. */
10908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_eap) {
10918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.neg_eap = 0;
10928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* Try to set up to use their suggestion, if possible */
10938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (CHAP_CANDIGEST(go->chap_mdtype, cichar))
10948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    try.chap_mdtype = CHAP_MDTYPE_D(cichar);
10958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    } else if (go->neg_chap) {
10968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/*
10978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * We were asking for our preferred algorithm, they must
10988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * want something different.
10998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 */
11008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (cichar != CHAP_DIGEST(go->chap_mdtype)) {
11018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) {
11028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/* Use their suggestion if we support it ... */
11038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			try.chap_mdtype = CHAP_MDTYPE_D(cichar);
11048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    } else {
11058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/* ... otherwise, try our next-preferred algorithm. */
11068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			try.chap_mdtype &= ~(CHAP_MDTYPE(try.chap_mdtype));
11078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (try.chap_mdtype == MDTYPE_NONE) /* out of algos */
11088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    try.neg_chap = 0;
11098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
11108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} else {
11118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    /*
11128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     * Whoops, they Nak'd our algorithm of choice
11138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     * but then suggested it back to us.
11148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     */
11158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    goto bad;
11168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
11178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    } else {
11188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/*
11198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * Stop asking for PAP if we were asking for it.
11208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 */
11218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.neg_upap = 0;
11228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
11238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else {
11258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
11278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * If we were asking for EAP, and they're Conf-Naking EAP,
11288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * well, that's just strange.  Nobody should do that.
11298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
11308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cishort == PPP_EAP && cilen == CILEN_SHORT && go->neg_eap)
11318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		dbglog("Unexpected Conf-Nak for EAP");
11328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
11348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * We don't recognize what they're suggesting.
11358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * Stop asking for what we were asking for.
11368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
11378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_eap)
11388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.neg_eap = 0;
11398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    else if (go->neg_chap)
11408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.neg_chap = 0;
11418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    else
11428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.neg_upap = 0;
11438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p += cilen - CILEN_SHORT;
11448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
11458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
11468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
11488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If they can't cope with our link quality protocol, we'll have
11498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * to stop asking for LQR.  We haven't got any other protocol.
11508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If they Nak the reporting period, take their value XXX ?
11518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
11528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NAKCILQR(CI_QUALITY, neg_lqr,
11538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     if (cishort != PPP_LQR)
11548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 try.neg_lqr = 0;
11558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     else
11568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 try.lqr_period = cilong;
11578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     );
11588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
11608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Only implementing CBCP...not the rest of the callback options
11618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
11628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NAKCICHAR(CI_CALLBACK, neg_cbcp,
11638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project              try.neg_cbcp = 0;
11648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project              );
11658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
11678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Check for a looped-back line.
11688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
11698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,
11708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      try.magicnumber = magic();
11718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      looped_back = 1;
11728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      );
11738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
11758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Peer shouldn't send Nak for protocol compression or
11768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * address/control compression requests; they should send
11778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * a Reject instead.  If they send a Nak, treat it as a Reject.
11788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
11798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NAKCIVOID(CI_PCOMPRESSION, neg_pcompression);
11808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NAKCIVOID(CI_ACCOMPRESSION, neg_accompression);
11818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
11838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Nak for MRRU option - accept their value if it is smaller
11848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * than the one we want.
11858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
11868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg_mrru) {
11878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	NAKCISHORT(CI_MRRU, neg_mrru,
11888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   if (treat_as_reject)
11898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		       try.neg_mrru = 0;
11908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   else if (cishort <= wo->mrru)
11918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		       try.mrru = cishort;
11928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   );
11938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
11948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
11968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Nak for short sequence numbers shouldn't be sent, treat it
11978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * like a reject.
11988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
11998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NAKCIVOID(CI_SSNHF, neg_ssnhf);
12008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
12028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Nak of the endpoint discriminator option is not permitted,
12038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * treat it like a reject.
12048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
12058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NAKCIENDP(CI_EPDISC, neg_endpoint);
12068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
12088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * There may be remaining CIs, if the peer is requesting negotiation
12098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * on an option that we didn't include in our request packet.
12108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If we see an option that we requested, or one we've already seen
12118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * in this packet, then this packet is bad.
12128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If we wanted to respond by starting to negotiate on the requested
12138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * option(s), we could, but we don't, because except for the
12148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * authentication type and quality protocol, if we are not negotiating
12158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * an option, it is because we were told not to.
12168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * For the authentication type, the Nak from the peer means
12178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * `let me authenticate myself with you' which is a bit pointless.
12188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * For the quality protocol, the Nak means `ask me to send you quality
12198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * reports', but if we didn't ask for them, we don't want them.
12208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * An option we don't recognize represents the peer asking to
12218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * negotiate some option we don't support, so ignore it.
12228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
12238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while (len >= CILEN_VOID) {
12248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p);
12258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p);
12268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen < CILEN_VOID || (len -= cilen) < 0)
12278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad;
12288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	next = p + cilen - 2;
12298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	switch (citype) {
12318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_MRU:
12328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if ((go->neg_mru && go->mru != DEFMRU)
12338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		|| no.neg_mru || cilen != CILEN_SHORT)
12348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
12358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETSHORT(cishort, p);
12368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cishort < DEFMRU) {
12378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.neg_mru = 1;
12388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.mru = cishort;
12398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
12408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_ASYNCMAP:
12428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF)
12438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		|| no.neg_asyncmap || cilen != CILEN_LONG)
12448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
12458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_AUTHTYPE:
12478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap ||
12488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		go->neg_eap || no.neg_eap)
12498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
12508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_MAGICNUMBER:
12528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_magicnumber || no.neg_magicnumber ||
12538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen != CILEN_LONG)
12548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
12558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_PCOMPRESSION:
12578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_pcompression || no.neg_pcompression
12588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		|| cilen != CILEN_VOID)
12598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
12608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_ACCOMPRESSION:
12628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_accompression || no.neg_accompression
12638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		|| cilen != CILEN_VOID)
12648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
12658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_QUALITY:
12678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR)
12688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
12698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_MRRU:
12718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_mrru || no.neg_mrru || cilen != CILEN_SHORT)
12728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
12738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_SSNHF:
12758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_ssnhf || no.neg_ssnhf || cilen != CILEN_VOID)
12768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
12778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    try.neg_ssnhf = 1;
12788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_EPDISC:
12808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_endpoint || no.neg_endpoint || cilen < CILEN_CHAR)
12818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
12828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
12848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p = next;
12858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
12888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * OK, the Nak is good.  Now we can update state.
12898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If there are any options left we ignore them.
12908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
12918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->state != OPENED) {
12928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (looped_back) {
12938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (++try.numloops >= lcp_loopbackfail) {
12948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		notice("Serial line is looped back.");
12958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		lcp_close(f->unit, "Loopback detected");
12968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		status = EXIT_LOOPBACK;
12978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
12988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else
12998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    try.numloops = 0;
13008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	*go = try;
13018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
13048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectbad:
13068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    LCPDEBUG(("lcp_nakci: received bad Nak!"));
13078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
13088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
13128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_rejci - Peer has Rejected some of our CIs.
13138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This should not modify any state if the Reject is bad
13148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * or if LCP is in the OPENED state.
13158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
13168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Returns:
13178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *	0 - Reject was bad.
13188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *	1 - Reject was good.
13198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
13208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
13218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_rejci(f, p, len)
13228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
13238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
13248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
13258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
13268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *go = &lcp_gotoptions[f->unit];
13278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char cichar;
13288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_short cishort;
13298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t cilong;
13308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options try;		/* options to request next time */
13318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    try = *go;
13338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
13358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Any Rejected CIs must be in exactly the same order that we sent.
13368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Check packet length and CI length at each step.
13378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If we find any deviations, then this packet is bad.
13388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
13398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define REJCIVOID(opt, neg) \
13408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
13418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_VOID && \
13428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_VOID && \
13438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
13448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_VOID; \
13458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(CILEN_VOID, p); \
13468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.neg = 0; \
13478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define REJCISHORT(opt, neg, val) \
13498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
13508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_SHORT && \
13518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_SHORT && \
13528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
13538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_SHORT; \
13548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
13558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p); \
13568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Check rejected value. */ \
13578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cishort != val) \
13588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
13598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.neg = 0; \
13608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define REJCICHAP(opt, neg, val) \
13628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
13638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_CHAP && \
13648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_CHAP && \
13658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
13668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_CHAP; \
13678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
13688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p); \
13698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cichar, p); \
13708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Check rejected value. */ \
13718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \
13728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
13738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.neg = 0; \
13748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.neg_eap = try.neg_upap = 0; \
13758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define REJCILONG(opt, neg, val) \
13778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
13788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_LONG && \
13798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_LONG && \
13808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
13818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_LONG; \
13828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
13838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETLONG(cilong, p); \
13848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Check rejected value. */ \
13858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilong != val) \
13868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
13878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.neg = 0; \
13888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define REJCILQR(opt, neg, val) \
13908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
13918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_LQR && \
13928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_LQR && \
13938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
13948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_LQR; \
13958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
13968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p); \
13978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETLONG(cilong, p); \
13988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Check rejected value. */ \
13998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cishort != PPP_LQR || cilong != val) \
14008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
14018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.neg = 0; \
14028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
14038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define REJCICBCP(opt, neg, val) \
14048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
14058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_CBCP && \
14068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_CBCP && \
14078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt) { \
14088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_CBCP; \
14098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
14108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cichar, p); \
14118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Check rejected value. */ \
14128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cichar != val) \
14138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
14148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.neg = 0; \
14158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
14168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define REJCIENDP(opt, neg, class, val, vlen) \
14178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg && \
14188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len >= CILEN_CHAR + vlen && \
14198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[0] == opt && \
14208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p[1] == CILEN_CHAR + vlen) { \
14218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int i; \
14228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= CILEN_CHAR + vlen; \
14238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, p); \
14248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cichar, p); \
14258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cichar != class) \
14268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad; \
14278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	for (i = 0; i < vlen; ++i) { \
14288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETCHAR(cichar, p); \
14298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cichar != val[i]) \
14308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad; \
14318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} \
14328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.neg = 0; \
14338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
14348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCISHORT(CI_MRU, neg_mru, go->mru);
14368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);
14378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCISHORT(CI_AUTHTYPE, neg_eap, PPP_EAP);
14388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!go->neg_eap) {
14398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	REJCICHAP(CI_AUTHTYPE, neg_chap, go->chap_mdtype);
14408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!go->neg_chap) {
14418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);
14428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
14438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
14448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);
14458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT);
14468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber);
14478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCIVOID(CI_PCOMPRESSION, neg_pcompression);
14488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCIVOID(CI_ACCOMPRESSION, neg_accompression);
14498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCISHORT(CI_MRRU, neg_mrru, go->mrru);
14508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCIVOID(CI_SSNHF, neg_ssnhf);
14518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REJCIENDP(CI_EPDISC, neg_endpoint, go->endpoint.class,
14528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      go->endpoint.value, go->endpoint.length);
14538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
14558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If there are any remaining CIs, then this packet is bad.
14568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
14578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (len != 0)
14588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	goto bad;
14598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
14608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Now we can update state.
14618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
14628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->state != OPENED)
14638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	*go = try;
14648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
14658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectbad:
14678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    LCPDEBUG(("lcp_rejci: received bad Reject!"));
14688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
14698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
14708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
14738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_reqci - Check the peer's requested CIs and send appropriate response.
14748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
14758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
14768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * appropriately.  If reject_if_disagree is non-zero, doesn't return
14778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * CONFNAK; returns CONFREJ if it can't return CONFACK.
14788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
14798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
14808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_reqci(f, inp, lenp, reject_if_disagree)
14818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
14828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *inp;		/* Requested CIs */
14838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int *lenp;			/* Length of requested CIs */
14848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int reject_if_disagree;
14858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
14868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *go = &lcp_gotoptions[f->unit];
14878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *ho = &lcp_hisoptions[f->unit];
14888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *ao = &lcp_allowoptions[f->unit];
14898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *cip, *next;		/* Pointer to current and next CIs */
14908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int cilen, citype, cichar;	/* Parsed len, type, char value */
14918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_short cishort;		/* Parsed short value */
14928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t cilong;		/* Parse long value */
14938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int rc = CONFACK;		/* Final packet return code */
14948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int orc;			/* Individual option return code */
14958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;			/* Pointer to next char to parse */
14968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *rejp;		/* Pointer to next char in reject frame */
14978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *nakp;		/* Pointer to next char in Nak frame */
14988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int l = *lenp;		/* Length left */
14998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
15018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Reset all his options.
15028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
15038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    BZERO(ho, sizeof(*ho));
15048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
15068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Process all his options.
15078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
15088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    next = inp;
15098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    nakp = nak_buffer;
15108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rejp = inp;
15118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while (l) {
15128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	orc = CONFACK;			/* Assume success */
15138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cip = p = next;			/* Remember begining of CI */
15148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (l < 2 ||			/* Not enough data for CI header or */
15158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p[1] < 2 ||			/*  CI length too small or */
15168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p[1] > l) {			/*  CI length too big? */
15178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LCPDEBUG(("lcp_reqci: bad CI length!"));
15188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    orc = CONFREJ;		/* Reject bad CI */
15198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    cilen = l;			/* Reject till end of packet */
15208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    l = 0;			/* Don't loop again */
15218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype = 0;
15228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto endswitch;
15238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
15248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p);		/* Parse CI type */
15258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p);		/* Parse CI length */
15268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	l -= cilen;			/* Adjust remaining length */
15278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	next += cilen;			/* Step to next CI */
15288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	switch (citype) {		/* Check CI type */
15308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_MRU:
15318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!ao->neg_mru ||		/* Allow option? */
15328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen != CILEN_SHORT) {	/* Check CI length */
15338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;		/* Reject CI */
15348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
15368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETSHORT(cishort, p);	/* Parse MRU */
15378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
15398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * He must be able to receive at least our minimum.
15408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * No need to check a maximum.  If he sends a large number,
15418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * we'll just ignore it.
15428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
15438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cishort < MINMRU) {
15448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFNAK;		/* Nak CI */
15458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CI_MRU, nakp);
15468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CILEN_SHORT, nakp);
15478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTSHORT(MINMRU, nakp);	/* Give him a hint */
15488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
15508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->neg_mru = 1;		/* Remember he sent MRU */
15518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->mru = cishort;		/* And remember value */
15528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
15538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_ASYNCMAP:
15558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!ao->neg_asyncmap ||
15568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen != CILEN_LONG) {
15578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
15588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
15608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETLONG(cilong, p);
15618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
15638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * Asyncmap must have set at least the bits
15648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * which are set in lcp_allowoptions[unit].asyncmap.
15658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
15668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if ((ao->asyncmap & ~cilong) != 0) {
15678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFNAK;
15688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CI_ASYNCMAP, nakp);
15698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CILEN_LONG, nakp);
15708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTLONG(ao->asyncmap | cilong, nakp);
15718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
15738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->neg_asyncmap = 1;
15748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->asyncmap = cilong;
15758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
15768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_AUTHTYPE:
15788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cilen < CILEN_SHORT ||
15798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		!(ao->neg_upap || ao->neg_chap || ao->neg_eap)) {
15808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/*
15818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * Reject the option if we're not willing to authenticate.
15828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 */
15838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		dbglog("No auth is possible");
15848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
15858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
15878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETSHORT(cishort, p);
15888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
15908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * Authtype must be PAP, CHAP, or EAP.
15918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     *
15928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * Note: if more than one of ao->neg_upap, ao->neg_chap, and
15938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * ao->neg_eap are set, and the peer sends a Configure-Request
15948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * with two or more authenticate-protocol requests, then we will
15958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * reject the second request.
15968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * Whether we end up doing CHAP, UPAP, or EAP depends then on
15978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * the ordering of the CIs in the peer's Configure-Request.
15988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project             */
15998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cishort == PPP_PAP) {
16018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* we've already accepted CHAP or EAP */
16028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (ho->neg_chap || ho->neg_eap ||
16038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    cilen != CILEN_SHORT) {
16048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE PAP, rejecting..."));
16058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    orc = CONFREJ;
16068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
16078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
16088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (!ao->neg_upap) {	/* we don't want to do PAP */
16098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    orc = CONFNAK;	/* NAK it and suggest CHAP or EAP */
16108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    PUTCHAR(CI_AUTHTYPE, nakp);
16118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (ao->neg_eap) {
16128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTCHAR(CILEN_SHORT, nakp);
16138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTSHORT(PPP_EAP, nakp);
16148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    } else {
16158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTCHAR(CILEN_CHAP, nakp);
16168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTSHORT(PPP_CHAP, nakp);
16178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
16188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
16198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
16208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
16218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ho->neg_upap = 1;
16228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
16238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
16248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cishort == PPP_CHAP) {
16258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* we've already accepted PAP or EAP */
16268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (ho->neg_upap || ho->neg_eap ||
16278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    cilen != CILEN_CHAP) {
16288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE CHAP, rejecting..."));
16298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    orc = CONFREJ;
16308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
16318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
16328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (!ao->neg_chap) {	/* we don't want to do CHAP */
16338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    orc = CONFNAK;	/* NAK it and suggest EAP or PAP */
16348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    PUTCHAR(CI_AUTHTYPE, nakp);
16358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    PUTCHAR(CILEN_SHORT, nakp);
16368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (ao->neg_eap) {
16378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTSHORT(PPP_EAP, nakp);
16388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    } else {
16398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTSHORT(PPP_PAP, nakp);
16408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
16418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
16428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
16438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		GETCHAR(cichar, p);	/* get digest type */
16448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (!(CHAP_CANDIGEST(ao->chap_mdtype, cichar))) {
16458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    /*
16468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     * We can't/won't do the requested type,
16478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     * suggest something else.
16488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     */
16498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    orc = CONFNAK;
16508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    PUTCHAR(CI_AUTHTYPE, nakp);
16518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    PUTCHAR(CILEN_CHAP, nakp);
16528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    PUTSHORT(PPP_CHAP, nakp);
16538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
16548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
16558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
16568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ho->chap_mdtype = CHAP_MDTYPE_D(cichar); /* save md type */
16578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ho->neg_chap = 1;
16588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
16598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
16608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cishort == PPP_EAP) {
16618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* we've already accepted CHAP or PAP */
16628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (ho->neg_chap || ho->neg_upap || cilen != CILEN_SHORT) {
16638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE EAP, rejecting..."));
16648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    orc = CONFREJ;
16658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
16668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
16678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (!ao->neg_eap) {	/* we don't want to do EAP */
16688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    orc = CONFNAK;	/* NAK it and suggest CHAP or PAP */
16698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    PUTCHAR(CI_AUTHTYPE, nakp);
16708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (ao->neg_chap) {
16718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTCHAR(CILEN_CHAP, nakp);
16728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTSHORT(PPP_CHAP, nakp);
16738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
16748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    } else {
16758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTCHAR(CILEN_SHORT, nakp);
16768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTSHORT(PPP_PAP, nakp);
16778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
16788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
16798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
16808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ho->neg_eap = 1;
16818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
16828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
16838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
16858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * We don't recognize the protocol they're asking for.
16868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * Nak it with something we're willing to do.
16878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * (At this point we know ao->neg_upap || ao->neg_chap ||
16888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * ao->neg_eap.)
16898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
16908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    orc = CONFNAK;
16918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    PUTCHAR(CI_AUTHTYPE, nakp);
16928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (ao->neg_eap) {
16938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CILEN_SHORT, nakp);
16948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTSHORT(PPP_EAP, nakp);
16958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    } else if (ao->neg_chap) {
16968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CILEN_CHAP, nakp);
16978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTSHORT(PPP_CHAP, nakp);
16988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
16998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    } else {
17008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CILEN_SHORT, nakp);
17018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTSHORT(PPP_PAP, nakp);
17028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
17038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
17048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_QUALITY:
17068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!ao->neg_lqr ||
17078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen != CILEN_LQR) {
17088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
17098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
17108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
17118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETSHORT(cishort, p);
17138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETLONG(cilong, p);
17148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
17168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * Check the protocol and the reporting period.
17178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * XXX When should we Nak this, and what with?
17188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
17198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cishort != PPP_LQR) {
17208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFNAK;
17218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CI_QUALITY, nakp);
17228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CILEN_LQR, nakp);
17238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTSHORT(PPP_LQR, nakp);
17248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTLONG(ao->lqr_period, nakp);
17258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
17268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
17278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
17288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_MAGICNUMBER:
17308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!(ao->neg_magicnumber || go->neg_magicnumber) ||
17318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen != CILEN_LONG) {
17328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
17338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
17348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
17358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETLONG(cilong, p);
17368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
17388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * He must have a different magic number.
17398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
17408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->neg_magicnumber &&
17418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilong == go->magicnumber) {
17428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilong = magic();	/* Don't put magic() inside macro! */
17438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFNAK;
17448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CI_MAGICNUMBER, nakp);
17458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(CILEN_LONG, nakp);
17468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTLONG(cilong, nakp);
17478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
17488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
17498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->neg_magicnumber = 1;
17508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->magicnumber = cilong;
17518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
17528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_PCOMPRESSION:
17558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!ao->neg_pcompression ||
17568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen != CILEN_VOID) {
17578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
17588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
17598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
17608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->neg_pcompression = 1;
17618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
17628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_ACCOMPRESSION:
17648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!ao->neg_accompression ||
17658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen != CILEN_VOID) {
17668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
17678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
17688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
17698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->neg_accompression = 1;
17708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
17718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_MRRU:
17738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!ao->neg_mrru || !multilink ||
17748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen != CILEN_SHORT) {
17758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
17768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
17778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
17788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETSHORT(cishort, p);
17808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* possibly should insist on a minimum/maximum MRRU here */
17818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->neg_mrru = 1;
17828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->mrru = cishort;
17838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
17848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_SSNHF:
17868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!ao->neg_ssnhf || !multilink ||
17878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen != CILEN_VOID) {
17888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
17898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
17908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
17918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->neg_ssnhf = 1;
17928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
17938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case CI_EPDISC:
17958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!ao->neg_endpoint ||
17968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen < CILEN_CHAR ||
17978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		cilen > CILEN_CHAR + MAX_ENDP_LEN) {
17988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
17998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
18008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
18018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETCHAR(cichar, p);
18028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    cilen -= CILEN_CHAR;
18038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->neg_endpoint = 1;
18048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->endpoint.class = cichar;
18058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->endpoint.length = cilen;
18068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    BCOPY(p, ho->endpoint.value, cilen);
18078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    INCPTR(cilen, p);
18088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
18098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	default:
18118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    LCPDEBUG(("lcp_reqci: rcvd unknown option %d", citype));
18128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    orc = CONFREJ;
18138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
18148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
18158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectendswitch:
18178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (orc == CONFACK &&		/* Good CI */
18188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    rc != CONFACK)		/*  but prior CI wasnt? */
18198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;			/* Don't send this one */
18208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (orc == CONFNAK) {		/* Nak this CI? */
18228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (reject_if_disagree	/* Getting fed up with sending NAKs? */
18238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		&& citype != CI_MAGICNUMBER) {
18248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;		/* Get tough if so */
18258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    } else {
18268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (rc == CONFREJ)	/* Rejecting prior CI? */
18278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    continue;		/* Don't send this one */
18288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		rc = CONFNAK;
18298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
18308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
18318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (orc == CONFREJ) {		/* Reject this CI */
18328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    rc = CONFREJ;
18338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cip != rejp)		/* Need to move rejected CI? */
18348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		BCOPY(cip, rejp, cilen); /* Move it */
18358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    INCPTR(cilen, rejp);	/* Update output pointer */
18368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
18378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
18388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
18408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If we wanted to send additional NAKs (for unsent CIs), the
18418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * code would go here.  The extra NAKs would go at *nakp.
18428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * At present there are no cases where we want to ask the
18438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * peer to negotiate an option.
18448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
18458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    switch (rc) {
18478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFACK:
18488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	*lenp = next - inp;
18498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
18508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFNAK:
18518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
18528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Copy the Nak'd options from the nak_buffer to the caller's buffer.
18538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
18548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	*lenp = nakp - nak_buffer;
18558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	BCOPY(nak_buffer, inp, *lenp);
18568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
18578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFREJ:
18588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	*lenp = rejp - inp;
18598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
18608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
18618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    LCPDEBUG(("lcp_reqci: returning CONF%s.", CODENAME(rc)));
18638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return (rc);			/* Return final code */
18648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
18658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
18688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_up - LCP has come UP.
18698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
18708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
18718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_up(f)
18728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
18738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
18748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *wo = &lcp_wantoptions[f->unit];
18758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *ho = &lcp_hisoptions[f->unit];
18768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *go = &lcp_gotoptions[f->unit];
18778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *ao = &lcp_allowoptions[f->unit];
18788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int mtu, mru;
18798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!go->neg_magicnumber)
18818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	go->magicnumber = 0;
18828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!ho->neg_magicnumber)
18838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ho->magicnumber = 0;
18848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
18868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Set our MTU to the smaller of the MTU we wanted and
18878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * the MRU our peer wanted.  If we negotiated an MRU,
18888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * set our MRU to the larger of value we wanted and
18898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * the value we got in the negotiation.
18908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Note on the MTU: the link MTU can be the MRU the peer wanted,
18918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * the interface MTU is set to the lowest of that, the
18928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * MTU we want to use, and our link MRU.
18938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
18948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    mtu = ho->neg_mru? ho->mru: PPP_MRU;
18958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU;
18968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef HAVE_MULTILINK
18978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!(multilink && go->neg_mrru && ho->neg_mrru))
18988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* HAVE_MULTILINK */
18998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	netif_set_mtu(f->unit, MIN(MIN(mtu, mru), ao->mru));
19008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ppp_send_config(f->unit, mtu,
19018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    (ho->neg_asyncmap? ho->asyncmap: 0xffffffff),
19028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    ho->neg_pcompression, ho->neg_accompression);
19038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ppp_recv_config(f->unit, mru,
19048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    (lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff),
19058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    go->neg_pcompression, go->neg_accompression);
19068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ho->neg_mru)
19088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	peer_mru[f->unit] = ho->mru;
19098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_echo_lowerup(f->unit);  /* Enable echo messages */
19118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    link_established(f->unit);
19138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
19148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
19178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_down - LCP has gone DOWN.
19188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
19198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Alert other protocols.
19208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
19218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
19228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_down(f)
19238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
19248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
19258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_options *go = &lcp_gotoptions[f->unit];
19268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_echo_lowerdown(f->unit);
19288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    link_down(f->unit);
19308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ppp_send_config(f->unit, PPP_MRU, 0xffffffff, 0, 0);
19328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ppp_recv_config(f->unit, PPP_MRU,
19338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    (go->neg_asyncmap? go->asyncmap: 0xffffffff),
19348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    go->neg_pcompression, go->neg_accompression);
19358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    peer_mru[f->unit] = PPP_MRU;
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_starting - LCP needs the lower layer up.
19418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
19428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
19438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_starting(f)
19448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
19458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
19468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    link_required(f->unit);
19478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
19488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
19518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_finished - LCP has finished with the lower layer.
19528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
19538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
19548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_finished(f)
19558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
19568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
19578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    link_terminated(f->unit);
19588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
19598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
19628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_printpkt - print the contents of an LCP packet.
19638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
19648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char *lcp_codenames[] = {
19658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    "ConfReq", "ConfAck", "ConfNak", "ConfRej",
19668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    "TermReq", "TermAck", "CodeRej", "ProtRej",
19678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    "EchoReq", "EchoRep", "DiscReq"
19688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
19698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
19718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_printpkt(p, plen, printer, arg)
19728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
19738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int plen;
19748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    void (*printer) __P((void *, char *, ...));
19758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    void *arg;
19768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
19778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int code, id, len, olen, i;
19788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *pstart, *optend;
19798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_short cishort;
19808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t cilong;
19818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (plen < HEADERLEN)
19838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
19848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pstart = p;
19858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    GETCHAR(code, p);
19868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    GETCHAR(id, p);
19878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    GETSHORT(len, p);
19888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (len < HEADERLEN || len > plen)
19898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
19908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *))
19928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	printer(arg, " %s", lcp_codenames[code-1]);
19938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    else
19948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	printer(arg, " code=0x%x", code);
19958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    printer(arg, " id=0x%x", id);
19968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    len -= HEADERLEN;
19978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    switch (code) {
19988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFREQ:
19998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFACK:
20008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFNAK:
20018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFREJ:
20028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* print option list */
20038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	while (len >= 2) {
20048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETCHAR(code, p);
20058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETCHAR(olen, p);
20068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p -= 2;
20078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (olen < 2 || olen > len) {
20088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
20098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
20108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    printer(arg, " <");
20118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    len -= olen;
20128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    optend = p + olen;
20138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    switch (code) {
20148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_MRU:
20158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen == CILEN_SHORT) {
20168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
20178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    GETSHORT(cishort, p);
20188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "mru %d", cishort);
20198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
20208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
20218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_ASYNCMAP:
20228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen == CILEN_LONG) {
20238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
20248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    GETLONG(cilong, p);
20258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "asyncmap 0x%x", cilong);
20268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
20278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
20288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_AUTHTYPE:
20298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen >= CILEN_SHORT) {
20308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
20318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "auth ");
20328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    GETSHORT(cishort, p);
20338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    switch (cishort) {
20348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    case PPP_PAP:
20358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, "pap");
20368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
20378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    case PPP_CHAP:
20388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, "chap");
20398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (p < optend) {
20408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    switch (*p) {
20418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    case CHAP_MD5:
20428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " MD5");
20438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				++p;
20448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
20458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef CHAPMS
20468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    case CHAP_MICROSOFT:
20478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " MS");
20488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				++p;
20498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
20508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    case CHAP_MICROSOFT_V2:
20528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " MS-v2");
20538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				++p;
20548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
20558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
20568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    }
20578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
20588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
20598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    case PPP_EAP:
20608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, "eap");
20618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
20628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    default:
20638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, "0x%x", cishort);
20648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
20658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
20668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
20678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_QUALITY:
20688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen >= CILEN_SHORT) {
20698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
20708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "quality ");
20718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    GETSHORT(cishort, p);
20728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    switch (cishort) {
20738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    case PPP_LQR:
20748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, "lqr");
20758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
20768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    default:
20778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, "0x%x", cishort);
20788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
20798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
20808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
20818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_CALLBACK:
20828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen >= CILEN_CHAR) {
20838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
20848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "callback ");
20858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    GETCHAR(cishort, p);
20868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    switch (cishort) {
20878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    case CBCP_OPT:
20888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, "CBCP");
20898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
20908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    default:
20918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, "0x%x", cishort);
20928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
20938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
20948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
20958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_MAGICNUMBER:
20968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen == CILEN_LONG) {
20978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
20988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    GETLONG(cilong, p);
20998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "magic 0x%x", cilong);
21008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
21018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
21028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_PCOMPRESSION:
21038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen == CILEN_VOID) {
21048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
21058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "pcomp");
21068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
21078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
21088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_ACCOMPRESSION:
21098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen == CILEN_VOID) {
21108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
21118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "accomp");
21128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
21138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
21148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_MRRU:
21158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen == CILEN_SHORT) {
21168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
21178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    GETSHORT(cishort, p);
21188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "mrru %d", cishort);
21198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
21208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
21218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_SSNHF:
21228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen == CILEN_VOID) {
21238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
21248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "ssnhf");
21258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
21268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
21278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case CI_EPDISC:
21288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef HAVE_MULTILINK
21298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen >= CILEN_CHAR) {
21308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    struct epdisc epd;
21318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
21328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    GETCHAR(epd.class, p);
21338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    epd.length = olen - CILEN_CHAR;
21348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (epd.length > MAX_ENDP_LEN)
21358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			epd.length = MAX_ENDP_LEN;
21368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (epd.length > 0) {
21378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			BCOPY(p, epd.value, epd.length);
21388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			p += epd.length;
21398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
21408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer(arg, "endpoint [%s]", epdisc_to_str(&epd));
21418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
21428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#else
21438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		printer(arg, "endpoint");
21448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
21458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
21468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
21478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    while (p < optend) {
21488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		GETCHAR(code, p);
21498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		printer(arg, " %.2x", code);
21508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
21518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    printer(arg, ">");
21528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
21538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
21548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case TERMACK:
21568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case TERMREQ:
21578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len > 0 && *p >= ' ' && *p < 0x7f) {
21588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    printer(arg, " ");
21598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    print_string((char *)p, len, printer, arg);
21608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p += len;
21618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    len = 0;
21628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
21638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
21648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case ECHOREQ:
21668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case ECHOREP:
21678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case DISCREQ:
21688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len >= 4) {
21698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETLONG(cilong, p);
21708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    printer(arg, " magic=0x%x", cilong);
21718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p += 4;
21728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    len -= 4;
21738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
21748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
21758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
21768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* print the rest of the bytes in the packet */
21788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (i = 0; i < len && i < 32; ++i) {
21798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(code, p);
21808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	printer(arg, " %.2x", code);
21818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
21828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (i < len) {
21838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	printer(arg, " ...");
21848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p += len - i;
21858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
21868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return p - pstart;
21888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
21898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
21918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Time to shut down the link because there is nothing out there.
21928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
21938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic
21958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid LcpLinkFailure (f)
21968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
21978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
21988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->state == OPENED) {
21998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	info("No response to %d echo-requests", lcp_echos_pending);
22008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        notice("Serial link appears to be disconnected.");
22018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        lcp_close(f->unit, "Peer not responding");
22028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	status = EXIT_PEER_DEAD;
22038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
22048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
22058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
22078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Timer expired for the LCP echo requests from this process.
22088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
22098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
22118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectLcpEchoCheck (f)
22128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
22138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
22148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    LcpSendEchoRequest (f);
22158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->state != OPENED)
22168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
22178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
22198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Start the timer for the next interval.
22208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
22218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (lcp_echo_timer_running)
22228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("assertion lcp_echo_timer_running==0 failed");
22238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval);
22248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_echo_timer_running = 1;
22258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
22268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
22288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * LcpEchoTimeout - Timer expired on the LCP echo
22298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
22308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
22328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectLcpEchoTimeout (arg)
22338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    void *arg;
22348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
22358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (lcp_echo_timer_running != 0) {
22368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        lcp_echo_timer_running = 0;
22378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        LcpEchoCheck ((fsm *) arg);
22388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
22398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
22408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
22428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * LcpEchoReply - LCP has received a reply to the echo
22438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
22448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
22468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_received_echo_reply (f, id, inp, len)
22478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
22488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int id;
22498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *inp;
22508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
22518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
22528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t magic;
22538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Check the magic number - don't count replies from ourselves. */
22558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (len < 4) {
22568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	dbglog("lcp: received short Echo-Reply, length %d", len);
22578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
22588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
22598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    GETLONG(magic, inp);
22608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (lcp_gotoptions[f->unit].neg_magicnumber
22618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& magic == lcp_gotoptions[f->unit].magicnumber) {
22628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("appear to have received our own echo-reply!");
22638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
22648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
22658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Reset the number of outstanding echo frames */
22678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_echos_pending = 0;
22688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
22698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
22718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * LcpSendEchoRequest - Send an echo request frame to the peer
22728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
22738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
22758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectLcpSendEchoRequest (f)
22768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
22778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
22788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t lcp_magic;
22798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char pkt[4], *pktp;
22808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
22828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Detect the failure of the peer at this point.
22838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
22848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (lcp_echo_fails != 0) {
22858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        if (lcp_echos_pending >= lcp_echo_fails) {
22868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project            LcpLinkFailure(f);
22878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    lcp_echos_pending = 0;
22888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
22898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
22908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
22928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Make and send the echo request frame.
22938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
22948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->state == OPENED) {
22958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        lcp_magic = lcp_gotoptions[f->unit].magicnumber;
22968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	pktp = pkt;
22978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTLONG(lcp_magic, pktp);
22988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        fsm_sdata(f, ECHOREQ, lcp_echo_number++ & 0xFF, pkt, pktp - pkt);
22998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	++lcp_echos_pending;
23008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
23018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
23028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
23048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_echo_lowerup - Start the timer for the LCP frame
23058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
23068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
23088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_echo_lowerup (unit)
23098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
23108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
23118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f = &lcp_fsm[unit];
23128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Clear the parameters for generating echo frames */
23148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_echos_pending      = 0;
23158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_echo_number        = 0;
23168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lcp_echo_timer_running = 0;
23178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* If a timeout interval is specified then start the timer */
23198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (lcp_echo_interval != 0)
23208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        LcpEchoCheck (f);
23218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
23228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
23248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lcp_echo_lowerdown - Stop the timer for the LCP frame
23258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
23268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
23288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlcp_echo_lowerdown (unit)
23298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
23308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
23318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f = &lcp_fsm[unit];
23328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (lcp_echo_timer_running != 0) {
23348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        UNTIMEOUT (LcpEchoTimeout, f);
23358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        lcp_echo_timer_running = 0;
23368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
23378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
2338